[做得多了就水了]事件选择

【描述】

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;

}



 

 

你可能感兴趣的:(事件)