POJ-2376 Cleaning Shifts---区间覆盖&贪心
题目链接:
https://vjudge.net/problem/POJ-2376
题目大意:
farmer John要安排他的牛清理牛棚,一共有T个牛棚要清理,每头牛可以清理相邻的牛棚。比如,一头牛可以清理4-7号牛棚。当然了,牛清理的牛棚可以重叠。现在要你求出可以完成牛棚的清理的最少头牛的个数,不可以就输出-1.
思路:
贪心题。题目意思很明显是求最少的区间覆盖掉大区间。先对这些时间段排好序(见代码),这个排序应该是没什么问题的。然后呢,第一头牛肯定要选,就从这头牛开始,选取下一头牛。下一头牛怎么选取呢?即在满足条件的牛里面(注意:满足条件的牛是只要开始工作时间 start>=cow[0].y+1 即可),选取右边界值最大的那个,因为这样子能够覆盖掉最多的时间段。以此类推,故贪心法求之。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 typedef long long ll; 9 int n, t; 10 struct node 11 { 12 int l ,r; 13 bool operator < (const node a)const 14 { 15 return l < a.l || l == a.l && r > a.r; 16 } 17 }; 18 node a[25005]; 19 int main() 20 { 21 while(scanf("%d%d", &n, &t) != EOF) 22 { 23 for(int i = 0; i < n; i++) 24 { 25 scanf("%d%d", &a[i].l, &a[i].r); 26 } 27 sort(a, a + n); 28 int ans = 0, end = 0, now = 0; 29 while(end < t) 30 { 31 int begin = end + 1; 32 for(int i = now; i < n; i++) 33 { 34 if(a[i].l <= begin)//要覆盖起点 35 { 36 end = max(end, a[i].r);//取最远的终点 37 } 38 else 39 { 40 now = i;//不能覆盖起点,说明之后的都不可以,直接跳出,记录下标 41 break; 42 } 43 } 44 if(end < begin)//没找到牛,直接跳出 45 { 46 ans = -1; 47 break; 48 } 49 else ans++; 50 } 51 cout<<ans<<endl; 52 } 53 return 0; 54 }
越努力,越幸运