【codevs 2913】建筑抢修

这是一篇关于解决‘建筑抢修’问题的文章,介绍了如何使用贪心策略进行建筑修复顺序的优化。文章中指出,初始的贪心思路有漏洞,并提供了修正后的正确方法:先按T2排序,T2相同则按T1排序,然后利用大根堆来动态调整修复顺序,以确保尽可能多的建筑得到修复。作者强调全面思考问题和运用基础数据结构的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述 Description
小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏: 经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者。但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏。现在的情况是:T部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。你的任务是帮小刚合理的制订一个修理顺序,以抢修尽可能多的建筑。

输入描述 Input Description
第一行是一个整数N,接下来N行每行两个整数T1,T2描述一个建筑:修理这个建筑需要T1秒,如果在T2秒之内还没有修理完成,这个建筑就报废了。

输出描述 Output Description
输出一个整数S,表示最多可以抢修S个建筑。

样例输入 Sample Input
4
100 200
200 1300
1000 1250
2000 3200

样例输出 Sample Output
3

数据范围及提示 Data Size & Hint
N<150000,t<=15000

【2017.10.16考试T1】

贪心。
考试时的贪心思路:分别按照T1和T2进行排序,对排序后的结果分别进行处理,能计入答案就计入答案,不能计入答案就看下一个。对两种结果取最大值。
策略有漏洞。如若先将t1=8,t2=18计入答案,再来一个t1=6,t2=20将超出答案的话,此时应当将前者取出放入后者才更优,而我的贪心策略没有这个过程,于是gg。

正解:
先按照T2排序,T2相同的按照T1排序。
建立一个大根堆,堆顶是所需时间最多的建筑。
从第一个建筑开始,如果当前建筑所需时间+抢修之前建筑所需时间<=当前T2,则将当前建筑放入堆里,更新总时间,ans++。
如果不满足上述条件,则将当前建筑所需时间与堆顶元素进行比较。若当前T1<堆顶T1,则弹出堆顶元素,将当前元素放入堆顶,更新总时间。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=200000+2;
int n,ans;
struct node
{
    int a,b;
}s[maxn];
/*bool cmp(node x,node y)
{
    return x.b<y.b;
}*/
bool cmp(node x,node y)
{
    return x.b==y.b?x.a<y.a:x.b<y.b;
}
priority_queue<node>q;
bool operator < (node a,node b)
{
    return a.a<b.a;
}
int main()
{
    int tot=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&s[i].a,&s[i].b);
    }
    sort(s+1,s+n+1,cmp);//按照截稿时间先后排序
    for(int i=1;i<=n;i++)
    {
        if(s[i].a+tot<=s[i].b)
        {
            q.push(s[i]);
            ans++;
            tot+=s[i].a;
        }
        else
        {
            node t=q.top();
            if(s[i].a>t.a) continue;
            else 
            {
                q.pop();
                tot-=t.a;
                q.push(s[i]);
                tot+=s[i].a;
            }
        }
    }
    printf("%d",ans);
    return 0;
}

好题好题。
以后,,应当考虑全面才是,思路经常不对就是自己的问题了。而且要联想到一些基本的数据结构,栈队列堆虽然没什么技术含量但常常成为解题的关键。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值