小刚在玩 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
- ================================================================================================================================
贪心的想, 通过排序, 让最先被报废的建筑 先修理. 并将该建筑的修理时间压入优先队列
如果当前时间与 该建筑的报废时间相冲突. 则与当前队列最大的时间相比较, 保证用最优时间.
因此使用优先队列 priority_queue 能快速比较.
================================================================================================================================
代码:
- #include<bits/stdc++.h>
- using namespace std;
- const int N = 15e4 + 10;
- struct Node{
- int t1,t2;
- }node[N];
- bool cmp(Node a,Node b) {return a.t2<b.t2;}
- priority_queue<int> que;
- int main()
- {
- int n; scanf("%d",&n);
- for(int i = 1;i <= n;++i) scanf("%d %d",&node[i].t1,&node[i].t2);
- sort(node+1,node+n+1,cmp);
- int time = 0,sum = 0;
- for(int i = 1;i <= n;++i)
- {
- // 当前时间 + 该建筑所需时间 <= 该建筑报废的时间
- if(time+node[i].t1<=node[i].t2)
- {
- time += node[i].t1;
- // 该时间压入优先队列
- que.push(node[i].t1);
- ++sum;
- }
- // 如果不满足上面的条件 且满足该建筑修理的时间小于优先队列中时间最久的
- // 且减去最大加上当前时间之后能 <= 该建筑报废的时间
- else if(node[i].t1<que.top()&&time-que.top()+node[i].t1<=node[i].t2)
- {
- time = time - que.top() + node[i].t1;
- que.pop();
- que.push(node[i].t1);
- }
- }
- printf("%d\n",sum);
- return 0;
- }
来源: http://www.bubuko.com/infodetail-2703998.html