贪心-poj 2376-Cleaning Shifts

来源:互联网 发布:网易新闻android源码 编辑:程序博客网 时间:2024/03/29 13:59

题目链接:

http://poj.org/problem?id=2376

题目意思:

安排n只牛干活,每只牛有固定的工作时间区间片段,问怎样安排使得使用的牛数最少且工作时间能覆盖1~T(给定)。

解题思路:

分析知,很明显的贪心。

先按每头牛的工作开始时间从小到大排序,如果开始时间一样则按结束时间从大到小来排,然后在当前牛工作的时间段内,选择一头牛使它的开始时间在前一头牛的工作时间内,且结束时间最长,然后选择它,反复进行,如果中间没有牛满足条件则直接跳出。

PS:假设当前牛工作时间段是s,e,由于是时间片(时间可以连续a,a+1也是可行的),所以选择下一头牛时,可以在s~e+1范围内选。

代码:

#include<iostream>#include<cmath>#include<cstdio>#include<sstream>#include<cstdlib>#include<string>#include<string.h>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#include<ctime>#include<bitset>#define eps 1e-6#define INF 0x3f3f3f3f#define PI acos(-1.0)#define ll __int64#define LL long long#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1#define M 1000000007#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define Maxn 26000int n,t;struct Inf{    int s,e;}inf[Maxn];bool cmp(struct Inf a,struct Inf b) //先按开始时间从小到大,然后再按结束时间从大到小{    if(a.s!=b.s)        return a.s<b.s;    return a.e>b.e;}int main(){   //freopen("in.txt","r",stdin);   //freopen("out.txt","w",stdout);   while(~scanf("%d%d",&n,&t))   {       bool ans=true;       for(int i=1;i<=n;i++)           scanf("%d%d",&inf[i].s,&inf[i].e);       sort(inf+1,inf+n+1,cmp);       if(inf[1].s>1)       {           printf("-1\n"); //不满足           continue;       }       if(inf[1].e>=t) //只要一个       {           printf("1\n");           continue;       }       int la=inf[1].e,ee=inf[1].e,num=1; //第一个的时间       for(int i=2;i<=n;)       {           while(inf[i].s<=(ee+1)&&i<=n) //再保证时间连续的情况下选择结束时间最大的那头牛           {               la=max(la,inf[i].e);               i++;           }           if(la>ee) //更新当前牛           {               num++;               ee=la;               if(la>=t) //已经达到要求了,不用再选牛了                   break;           }           else //选不出新的牛了 game over           {               ans=false;               break;           }       }       if(la<t) //注意最后的判断情况 wa了好几发       {           printf("-1\n");           continue;       }       if(!ans)            printf("-1\n");       else            printf("%d\n",num);   }   return 0;}


0 0
原创粉丝点击