您的位置:首页 > 其它

堆--建筑抢修nkoj2375

2016-07-27 19:21 399 查看
建筑抢修
Time Limit:10000MS  Memory Limit:65536K
Case Time Limit:1000MS
Description
机关城内只有hy一个修理工,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间。同时,hy修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。 

hy忙于四处修理建筑,无暇进行计算,所以他希望你可以告诉他他最多可以抢修多少个建筑。
Input
第一行是一个整数N, 

接下来N行每行两个整数T1,T2描述一个建筑:修理这个建筑需要T1秒,如果在T2秒之内还没有修理完成,这个建筑就报废了。
Output
输出一个整数S,表示最多可以抢修S个建筑。
Sample Input

4
100 200
200 1300
1000 1250
2000 3200


Sample Output

3


Hint
N<150000,T1<T2<2^31

分析:

1.这道题采用了堆维护的思想。但是其实质是贪心。

2.首先我们先按照时间限制T2排序。

3.贪心的想,对于每一个建筑,我们等它快到限制的时候再修复它。

4.因为是想让数量最多,再贪心的想:我们要选时间尽量短的。

5.那么我们可以维护一个大根堆,每次有冲突时,也即当前点无法修复的时候。如果当前的点的时间小于堆顶元素,就弹出堆顶元素并压入当前点。


注意到:代码中记录当前用时总和的tot要用long long(显然,tot-max=t1*n)

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
inline void _read(int &x){
char t=getchar();bool sign=true;
while(t<'0'||t>'9')
{if(t=='-')sign=false;t=getchar();}
for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';
if(!sign)x=-x;
}
int n;
int ans=0;
struct node{
int t1,t2;
};
node house[150005];
bool cmp(node a,node b){
return a.t2<b.t2;
}
priority_queue<int> heap;
int main(){
int i,j,k;
long long tot=0;
_read(n);
for(i=1;i<=n;i++){
_read(house[i].t1);
_read(house[i].t2);
}
sort(house+1,house+1+n,cmp);
for(i=1;i<=n;i++){
if(tot+house[i].t1<=house[i].t2){
heap.push(house[i].t1);
tot+=house[i].t1;
}
else if(tot+house[i].t1>house[i].t2&&heap.size()&&heap.top()>house[i].t1){
tot-=heap.top();
heap.pop();
heap.push(house[i].t1);
tot+=house[i].t1;
}
}
cout<<heap.size();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: