题面
小刚在玩(JSOI)提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,(T)部落消灭了所有
(z)部落的入侵者。但是T部落的基地里已经有(N)个建筑设施受到了严重的损伤,如果不尽快修复的话,这
些建筑设施将会完全毁坏。现在的情况是:(T)部落基地里只有一个修理工人,虽然他能瞬间到达任何一
个建筑,但是修复每个建筑都需要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,
不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。你的任
务是帮小刚合理的制订一个修理顺序,以抢修尽可能多的建筑。
输入格式
第一行是一个整数(N),接下来(N)行每行两个整数(T1,T2)描述一个建筑:修理这个建筑需要(T1)秒,如果在
(T2)秒之内还没有修理完成,这个建筑就报废了。
输出格式
输出一个整数(S),表示最多可以抢修(S)个建筑.
输入输出样例
输入
4
100 200
200 1300
1000 1250
2000 3200
输出 #1复制
3
说明/提示
(N < 150,000; T1 < T2 < maxlongint)
思路
先把所有的建筑的 (T2) 按照从小到大的顺序排个序,然后再将建筑逐次的“修复”。 “修复”的过程中,我们
会遇到这样的状况:修复当前的建筑需要花费的时间加上已经使用了的时间,超过了修复当前建筑的截
止时间。如果排在这个建筑前面的已经被修复了的建筑中,有某个建筑的修复时间大于当前这个建筑
的修复时间,那么就不修复那个建筑,反而把当前的建筑修复了(取代)。 这会将当前已经使用的时间
减少,为后来修复更多的建筑提供了更大的可能。 (可以用Exchange Argument----easily证明)
代码
#include<bits/stdc++.h>
using namespace std;
priority_queue<int,vector<int> ,less<int> > heap;
long long n;
const int N=2001000;
struct node{
long long t1,t2;
}pot[N];
long long ans;
long long sum;
bool cmp(node a,node b)
{
return a.t2<b.t2;
}
int main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&pot[i].t1,&pot[i].t2);
}
sort(pot+1,pot+1+n,cmp);
for(int i=1;i<=n;i++)
{
sum+=pot[i].t1;
heap.push(pot[i].t1);
if(sum<=pot[i].t2)
{
ans++;
}
else{
sum-=heap.top();
heap.pop();
}
}
cout<<ans<<endl;
return 0;
}