【JSOI2007】建筑抢修 贪心+堆
2015-10-13 09:17
435 查看
Description
小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者。但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏。现在的情况是:T部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。你的任务是帮小刚合理的制订一个修理顺序,以抢修尽可能多的建筑。Input
第一行是一个整数N,接下来N行每行两个整数T1,T2描述一个建筑:修理这个建筑需要T1秒,如果在T2秒之内还没有修理完成,这个建筑就报废了。Output
输出一个整数S,表示最多可以抢修S个建筑.N < 150,000; T1 < T2 < maxlongintSample Input
4100 200
200 1300
1000 1250
2000 3200
Sample Output
3bzoj1029
第一眼以为直接贪心+sort就能过,结果:10分(codevs交的)。当时觉得和UVA-11729很像……
我的贪心策略是:越早报废的越早修,若相等则修的越快越早修。
后来想想显然不对…
正解:先按报废时间由小到大排序,这样能使报废晚的能余出时间照顾报废早的。
然后从第一个开始,若当前建筑的修理时间+之前的总时间小于等于当前建筑的报废时间,则扔进堆里,ans++。
若大于,这时要从它前面所有建筑中选一个修理时间最长的(记为y)和它比较,
若当前建筑修理时间 > y,则不扔进堆中。
若当前建筑修理时间 < y,则把y替换成当前建筑。
这样能保证时间利用率最高,修理更多的建筑。
代码:
[code]#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int size=200010; struct edge{ int a,b; }l[size]; bool cmp(edge a,edge b) { return a.b==b.b? a.a<b.a :a.b<b.b; } priority_queue<edge> q; bool operator <(edge a,edge b) { return a.a<b.a; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&l[i].a,&l[i].b); } sort(l+1,l+1+n,cmp); int ans=0,tot=0; for(int i=1;i<=n;i++) { if(l[i].a+tot<=l[i].b) {ans++;q.push(l[i]);tot+=l[i].a;} else { edge x=q.top(); q.pop(); tot-=x.a; if(l[i].a<x.a) {q.push(l[i]);tot+=l[i].a;} else {q.push(x); tot+=x.a;} } } printf("%d",ans); return 0; }
相关文章推荐
- 【转】JavaScript中的setInterval用法
- gulpjs的使用介绍及技巧
- JavaScript 对象
- Jsoup 抓取网页信息(2) 需要Login的网页信息抓取
- Jsoup 抓取网页信息(1) 抓取 国际疾病码
- javascript base库
- 复习javascript基础 (1)
- Ember.js 入门指南——处理事件
- 自定义javascript log方法
- 编写高性能Javascript
- JSP中图片的上传与显示方法实例详解
- javascript正则表达式和字符串RegExp and String(一)
- javascript正则表达式和字符串RegExp and String(二)
- JS实现带圆弧背景渐变效果的导航菜单代码
- JS实现的简洁二级导航菜单雏形效果
- JS实现自动定时切换的简洁网页选项卡效果
- JS实现左右拖动改变内容显示区域大小的方法
- 有关json_decode乱码及NULL的问题
- 快速学习JavaScript的6个思维技巧
- 深入学习JavaScript对象