Description
小剛在玩JSOI提供的一個稱之爲“建築搶修”的電腦遊戲:經過了一場激烈的戰鬥,T部落消滅了所有z部落的入侵者。但是T部落的基地裏已經有N個建築設施受到了嚴重的損傷,如果不盡快修復的話,這些建築設施將會完全毀壞。現在的情況是:T部落基地裏只有一個修理工人,雖然他能瞬間到達任何一個建築,但是修復每個建築都需要一定的時間。同時,修理工人修理完一個建築才能修理下一個建築,不能同時修理多個建築。如果某個建築在一段時間之內沒有完全修理完畢,這個建築就報廢了。你的任務是幫小剛合理的制訂一個修理順序,以搶修儘可能多的建築。
Input
第一行是一個整數N,接下來N行每行兩個整數T1,T2描述一個建築:修理這個建築需要T1秒,如果在T2秒之內還沒有修理完成,這個建築就報廢了。
Output
輸出一個整數S,表示最多可以搶修S個建築.N < 150,000; T1 < T2 < maxlongint
Sample Input
4
100 200
200 1300
1000 1250
2000 3200
Sample Output
3
HINT
Source
排序+貪心+小根堆。由“搶修儘量多的建築”可以知道各建築都是等價的,那麼貪心策略爲:1、能搶修的都搶修了。2、若時限內搶修不了,就檢查之前已修好的建築中有沒有不如當前優的(時間比當前長的),替換之。
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
struct node{
int t1,t2;
}a[151000];
int n,timenow,ans;
priority_queue<int,vector<int>,less<int> >now;
inline void read(int &x)
{
x=0;int f=1;char t=getchar();
while((t<48)or(t>57)){if(t=='-')f=-1;t=getchar();}
while((t>=48)and(t<=57)){x=(x*10)+t-48;t=getchar();}
x*=f;
}
bool cmp(node x,node y)
{
return x.t2<y.t2;
}
int main()
{
read(n);
for (int i=1;i<=n;++i) read(a[i].t1),read(a[i].t2);
sort(a+1,a+n+1,cmp);
for (int i=1;i<=n;++i)
if (a[i].t1+timenow<=a[i].t2)
{
timenow+=a[i].t1;
now.push(a[i].t1);
++ans;
}
else
{
if (!now.empty())
{
int t=now.top();
if (a[i].t1<t)
{
now.pop();
timenow-=(t-a[i].t1);
now.push(a[i].t1);
}
}
}
printf("%d",ans);
return 0;
}