题目描述 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
/*
任务==建筑
need:完成每个任务(修理)所需要的时间 rest:剩余的时间(楼(任务)的保质期)
Q: 给出 各个任务所需要的时间 以及 各个任务所剩余的时间 问最多可以完成多少个任务
∵要求最多,∴要用到贪心的思想,那么考虑,如何才能完成最多呢?
每个任务需要何时完成取决于它的 need 及 rest
★所以可以有两种方案:
1)先做需要时间少的 2)先做剩余时间少的
1):容易看出,完成当前任务所需要的时间 决定了 其它任务的剩余时间的长短,
也就是说,其它任务的剩余时间 需要减去 当前任务所需要的时间,
由此来看,方法1)可行 所以用样例脑跑一下,惊人的发现只能完成两个
于是乎
2):1)行不通则考虑2):像食物一样,保质期越短,坏得越快,若要最大限度的
吃掉食物不浪费,则先吃保质期短的,而任务的“保质期”就是它的rest,先做rest少的,
可以最大程度避免任务“到期”,这样看来,也对,试一下样例,神奇般的对了
But why?rest小若need大也会是其它的过期呀?
Because 从rest小的开始做,若遇到过期的,就找一个之前完成的但need比大大的替换,
以此类推不断跟新答案,所以前面完成哪一个都不会影响后面的选择,
∵可以不断更新替换为最优的(dp的无后效性思想)而若从need小的开始做,遇到过期的,
则无法从之前完成的中找一个换掉,因为 要从need小的开始做,必然要sort一遍,
则之前完成的 的need不可能比它大,也就是说,前面的直接决定了后面的能否被完成,
即:遇到过期,不能更新
所以,能更新的肯定更优啦!
怎样实现——>优先队列,保证每一次取出的都是need最大的,以便更新数据
用dp:不能保证 每一次取出的都是need最大的,且二维数组就会爆空间
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int size=200010;
struct edge{
int need,rest;
}l[size];
bool cmp(edge a,edge b)
{
return a.rest==b.rest? a.need<b.need :a.rest<b.rest;
}
priority_queue<edge> q;
bool operator <(edge a,edge b) //重载 < 运算符
{
return a.need<b.need;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&l[i].need,&l[i].rest); //need , rest
}
sort(l+1,l+1+n,cmp); //small->big
int ans=0,tot=0; //tot:之前已经用的时间
for(int i=1;i<=n;i++)
{
if(l[i].need+tot<=l[i].rest) //时间够用 : 入堆
{
ans++; q.push(l[i]); tot+=l[i].need;
}
else
{ //堆顶
edge x=q.top(); q.pop();
tot-=x.need;
if(l[i].need<x.need) {q.push(l[i]); tot+=l[i].need;}
else {q.push(x); tot+=x.need;}
}
}
printf("%d",ans);
return 0;
}