[做得多了就水了]事件选择
【描述】
Dragon开了一个新的律师事务所,他每天需要处理很多的事情:每一个顾客要求Dragon在某一段固定的时间内为其提供咨询服务。具体的说,第i名顾客需要Dragon在时间[ai, bi]中为其服务。假如Dragon同学答应为顾客i提供咨询,那么在时间[ai, bi]中,Dragon同学就不能再为第二名顾客提供服务,但是在对顾客i的服务结束后可以立刻可对下一名顾客服务,就是说在服务顾客([1..3])后可直接服务([3..4])。现在Dragon同学希望能给最多的顾客提供服务。
我们认为初始时刻为0。
【输入格式】
第一行一个正整数n,表示顾客总数。然后n行每行两个正整数a[i]、b[i],描述第i名顾客的要求。
【输出格式】
一行一个正整数表示最多能服务的顾客。
【样例输入】
3
1 3
2 4
3 5
【样例输出】
2
【数据范围】
0 <= a[i] < b[i] <= 100000;
0 < n < 100000。
【分析】
这是经典的叫什么任务分配的动归。f[i]表示i时刻能得到的最多的人数。从后向前f[i]=max(f[i-1],f[c[p].end]+1),其中c[p].str等于i。
//100%
#include <stdio.h>
#include <stdlib.h>
#define maxn 100010
int f[maxn];
struct ss
{
int str,end;
} c[maxn];
int n,p;
int cmp(const void*a,const void*b)
{
ss c=*(ss*)a,d=*(ss*)b;
if (c.str<d.str) return -1;
return 1;
}
int main()
{
freopen("affair.in","r",stdin);
freopen("affair.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;++i) scanf("%d%d",&c[i].str,&c[i].end);
c[0].str=-1;
qsort(c,n+1,sizeof(ss),cmp);
p=n;
for (int i=c[n].str;i>=0;--i)
{
f[i]=f[i+1];
while (c[p].str>i) --p;
if (c[p].str==i)
while (c[p].str==i)
{
if (f[c[p].end]+1>f[i]) f[i]=f[c[p].end]+1;
--p;
}
}
printf("%d\n",f[0]);
return 0;
}
浙公网安备 33010602011771号