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

【描述】

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;
}

 

 

posted @ 2010-09-22 18:12  Sephiroth.L.  阅读(237)  评论(0编辑  收藏  举报