题目链接:
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 26000
int 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;
}