poj 2376解题报告(详细) 带几组测试数据

来源:互联网 发布:yum安装hba卡rpm包 编辑:程序博客网 时间:2024/05/21 08:41

题目链接:http://poj.org/problem?id=2376

farmer John要安排他的牛清理牛棚,一共有T个牛棚要清理,每头牛可以清理相邻的牛棚。比如,一头牛可以清理4-7号牛棚。当然了,牛清理的牛棚可以重叠。现在要你求出可以完成牛棚的清理的最少头牛的个数,不可以就输出-1.

一道区间重叠问题。排序+贪心可解。但是题目有个陷阱,容易让人走入思维误区。
给出2个区间。
2 5
6 8
如果用数轴表示,这个区间应该是不重合的。但是,实际情况是,一头牛清理完2-5号,下一头牛可以从6号开始清理,这很正常嘛。然后讨论区很多人(包括我)一开始都认为是最多到5号开始清的。

先来提出贪心策略吧。
先给出几个区间。我们要填满1-10区间

1 7
1 5
5 9
3 10
9 10

在开始节点相同的情况是我们优先选择结束节点大的。1 7。
下一步,在上一个选择的区间的范围内(注意1 7这个区间可以选择8为开始节点的区间)我们选择结束节点大的3 10区间.然后结果出来了,我们只要2个区间就可以覆盖整个目标区间了。
概括起来就是,选择开始节点在上一区间范围内结束节点大的区间。

這题就可以解决了?当然不是了。
还有些细节要处理,首先是题目给的测试据不是按顺序的,每次选择区间如果遍历整个数组就显得效率不高了。所以应该要对给出的区间进行排序。按什么排呢?开始节点还是结束节点?在这题里,2种都可以,我觉得按开始节点排更符合常人的思考习惯。

要注意的是,如果用两个数组保存区间的start和end的话,就要自己编写排序函数了,如果调用stl的sort(),开始数组的值还跟结束数组对应吗?

更好的方法,用stl的pair,first存放开始,second存放结束,这样直接调用sort,整个pair数组排好了。int早就定义了小于运算符,sort针对pair是按first来排序的。

当然也可以定义数据结构或者类,然后重载小于运算符,在调用sort()。

付测试数据,来自讨论区
用freopen测试,这个方便很多,不用一次一次输。
可以改变了标准输入流(键盘),从文本读取。
freopen(“input.txt”,”r”,stdin);
此方法非常好,建议用上。不然每次调试一个一个输很蛋疼。
第一组:

input    3 10    1 5    6 10    10 10output    2

第二组:

input    4 100    21 50    50 81    1 20    80 99output    -1

第三组

    input        6 10        1 5        2 6        3 4        4 5        7 10        2 3    output        -1
0 0