`
阿尔萨斯
  • 浏览: 4166868 次
社区版块
存档分类
最新评论

HDU 3650 Hot Expo(线段覆盖==离散化)

 
阅读更多

HDU 3650 Hot Expo(线段覆盖==离散化)

http://acm.hdu.edu.cn/showproblem.php?pid=3650

题意:

一个人要去参加n项活动,这些活动给出了开始时间和结束时间.他只能在每天的指定时间段去参加每项活动.问你他最少要花多少天才能参加完这些活动?

分析:

把一天的时间24*3600秒看成是一个0到24*3600的数轴.那么每个活动其实就覆盖了数轴上的一段线段.然后我们看数轴上的哪段子线段被覆盖最多次,那个最多次数就是我们需要的天数.

本题类似ZOJ1610(但是却有差别):

http://blog.csdn.net/u013480600/article/details/39502473

解法类似上题ZOJ1610,但是下面举个例子:

如果两个活动[1,2] [2,3]需要进行,那么最少需要几天?答案是2.因为在第2秒的时刻同时有两个活动需要进行,所以是需要2天的. 但是如果同样拿到ZOJ1610去计算那么线段的最大覆盖数就是1(不是2). 因为ZOJ1610明说的是线段,线段上任何一点是可以无穷小的. 而本题的时间单位是秒,也就是说2秒这点不是无穷小,它也是一个区间的. 所以这就是本题和ZOJ1610的区别.

问题是如何解决这个小差别呢? 就是在表示原始线段覆盖的时候,然后它把末尾的那小段也覆盖了就行.(具体看代码标记处)

也就是说:假设原始线段被x坐标离散化分为了0 1 4 5 四个点.现在有一个原始活动为[0,1],那么它的覆盖区间是[0,1]和[1,4].(不仅仅是[0,1]) 然后再来一个活动[1,4],它的覆盖区间是[1,4]和[4,5].这样我们就至少需要2天才行.

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100*2+5;

struct Node
{
    int x1,x2;
}nodes[maxn];

int n;
int x[maxn];
int num;

int main()
{
    while(scanf("%d",&n)==1 && n)
    {
        num=0;
        for(int i=0;i<n;++i)
        {
            scanf("%d%d",&nodes[i].x1,&nodes[i].x2);
            x[num++]=nodes[i].x1;
            x[num++]=nodes[i].x2;
        }
        sort(x,x+num);
        num=unique(x,x+num)-x;

        int cover[maxn];//线段覆盖数
        memset(cover,0,sizeof(cover));
        for(int i=0;i<n;++i)
        {
            int L_x=lower_bound(x,x+num,nodes[i].x1)-x;
            int R_x=lower_bound(x,x+num,nodes[i].x2)-x;

            for(int j=L_x;j<=R_x;++j) ++cover[j];
        }
        int ans=0;
        for(int i=0;i<=num;++i) ans=max(ans,cover[i]);
        printf("%d\n",ans);
    }
    return 0;
}

分享到:
评论
Global site tag (gtag.js) - Google Analytics