POJ 2376 贪心

题意:FJ希望它的牛做一些清洁工作。有N只牛和T个时间段,每只牛可以承担一段时间内的工作。FJ希望让最小数量的牛覆盖整个T,求出其数量。若无法覆盖整个T,则输出-1.

分析:首先要注意T表示T个时间段,也就是说1就是一个时间段,而[1, 2]是两个时间段。在这个问题上,我们要做到的是用最小的牛覆盖整个区间。比较容易想到的是先将牛按开始时间排序,因为如果一开始就覆盖不了那么后续就没有意义可以直接输出-1。贪心选取在满足当前开始时间的前提下,其结束时间的大的牛,因为在满足开始前提下,当然是覆盖得越多越好。可以简单设想如果可以用一只覆盖得比较小的牛来做到最优结果,那么用覆盖得最大的必然也是最优结果。

     因此算法的简单实现如下:先对牛按开始时间排序,然后用一个finalTime表示当前上一只牛的结束时间(初始化为0)。对于接下来的每一只牛,检查其开始时间是否满足不大于上一次结束时间+1。在这个前提下,选取最大的结束时间。这样就能得到最优结果。若在这个过程,无法找到一只牛满足条件,则表示无法覆盖整个空间(因为牛是按开始时间排序的,现在覆盖不了,后面的更加覆盖不了)。

 

 1 #include <cstdio>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 typedef pair<int, int> P;
 7 
 8 const int MAX_N = 25000;
 9 const int MAX_T = 1000000;
10 
11 //输入
12 int N, T;
13 P a[MAX_N];
14 
15 //每次选取开始时间不大于当前结束时间,及其结束时间最大的牛
16 void solve(){
17     //贪心
18     int ans = 0;                //结果
19     int finalTime = 0;            //当前结束时间
20     //按开始时间排序
21     sort(a, a + N);
22     for(int i = 0; i < N && finalTime < T;){
23         int maxFinal = a[i].second, tmp = i;
24         //找符合开始时间的前提下,结束时间最大的牛
25         while(i < N && a[i].first <= finalTime + 1){
26             maxFinal = max(maxFinal, a[i].second);
27             i ++;
28         }
29         if(tmp == i || finalTime >= maxFinal){
30             //无法找到合适的牛
31             printf("-1\n");
32             return;
33         }
34 
35         ans ++;
36         finalTime = maxFinal;
37     }
38     if(finalTime < T)
39         printf("-1\n");
40     else
41         printf("%d\n", ans);
42 }
43 
44 int main(int argc, char const *argv[]){
45 
46     scanf("%d %d", &N, &T);
47     for(int i = 0; i < N; i ++)
48         scanf("%d %d", &a[i].first, &a[i].second);
49     solve();
50 
51     return 0;
52 }

 

posted @ 2014-03-18 08:48  7hat  阅读(357)  评论(0编辑  收藏  举报