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 }
原文地址:https://www.cnblogs.com/fzl194/p/8834395.html