加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

HUD 2491 排序方法 贪心

(2010-08-28 19:01:01)
标签:

hud

2491

排序方法

贪心

it

分类: 杂题

题目描述:

一个地方,只有一个牧师。

现在要举行n个婚礼, 告诉你每个婚礼的开始时间s和结束时间t。

牧师要在每个婚礼上进行主持,主持的时间至少比整个婚礼时间的一半还要多。

主持时间不能间断。

问你能不能找到一个合理的方案,使牧师满足所有婚礼的需求。

解题报告:

一开始想到贪心,但是很快就找到的反例。

随后,利用主持时间比婚礼的一半时间还要多,突然意识到:

任意的两个婚礼的主持时间是有序的,即:

对于婚礼i和婚礼j,如果婚礼i能在婚礼j之前主持,那么婚礼j必然“不能”在婚礼i之前主持。

反之同理。

根据这个条件,就可以排序出主持的顺序了,然后从头一边On的遍历,把每个婚礼的主持时间尽量往前靠,如果没有冲突,就是YES,否则NO

注意:给你的婚礼时间是时间点,比如1 5,表示婚礼从1开始,在5结束,即只有4的时间,而不是5.所以为了处理方便,5--即可。

代码可读性很好,如下:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
struct Node{
    ll a,b,mid,len;
};
struct Node node[100010];
int n;
bool flag;
bool cmp(Node x, Node y){
    if(x.a < y.a)
        return x.a + x.len <= y.mid;
    else if(x.a == y.a)
        return x.b < y.b;
    else if (y.a + y.len <= x.mid) return false;
    else return true;
}
ll mmax(ll a, ll b){
    if(a>b) return a;
    return b;
}
int main(){
    while(scanf("%d",&n)){
        if(n==0)
            break;
        for(int i=1;i<=n;i++){
            scanf("%I64d %I64d",&node[i].a,&node[i].b); node[i].b--;
            node[i].len = (node[i].b-node[i].a + 1LL)/2LL + 1LL;
            node[i].mid = node[i].b - node[i].len + 1LL;
        }
        flag = true;
        sort(node+1,node+1+n,cmp);
        if (!flag)
        {
            printf("NO\n");
            continue;
        }
        int ans = 1;
        ll now = 0;
        for(int i=1;i<=n;i++){
            if(node[i].mid < now){
                ans = 0;
                break;
            }
            ll st = mmax(node[i].a,now);
            now = st + node[i].len;
        }
        if(ans==1)  printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有