【贪心+堆】BZOJ1029(JSOI2007)[建筑抢修]题解
2017-06-17 16:32
357 查看
题目概述
有n个建筑,每个建筑有修复时间T1和报废时间T2,一个建筑在报废后就不能修了。问最多能修多少建筑。解题报告
刚看题目会想到动态规划,但是时间空间都承受不住,于是想到贪心。为了优先考虑终止时间早的建筑,我们按照终止时间从小到大排个序。记录最后的时间lst,对于一个建筑,如果lst+修建筑的时间<=建筑报废的时间,那么就直接修。但如果不满足怎么办?为了能让这个建筑得到修复,我们可以将前面的一个已修复的建筑换掉,从而给这个建筑腾出时间,而换掉修复时间最长的建筑才能腾出更多的时间。所以我们可以用堆选出修复时间最长的建筑。
上述贪心还有个漏洞,就是如果当前建筑修复时间比之前最长修复时间还要长的话,肯定就不选当前建筑了。到这里,这道题目就解完了。
示例程序
#include<cstdio> #include<queue> #include<algorithm> using namespace std; const int maxn=150000; int n,ans; struct data { int s,t; bool operator < (const data &c) const {return t<c.t;} }; data a[maxn+5]; priority_queue<int> heap_b; int main() { freopen("program.in","r",stdin); freopen("program.out","w",stdout); scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&a[i].s,&a[i].t); sort(a+1,a+1+n); int lst=0;while (!heap_b.empty()) heap_b.pop(); for (int i=1;i<=n;i++) if (lst+a[i].s<=a[i].t) lst+=a[i].s,ans++,heap_b.push(a[i].s); else if (a[i].s<heap_b.top()&&lst-heap_b.top()+a[i].s<=a[i].t) lst+=a[i].s-heap_b.top(),heap_b.pop(),heap_b.push(a[i].s); printf("%d\n",ans); return 0; }
相关文章推荐
- bzoj1029 [JSOI2007]建筑抢修(贪心)
- [JSOI2007]建筑抢修 BZOJ1029 BSOJ2228 CODEVS2913 贪心+大根堆
- BZOJ1029: [JSOI2007]建筑抢修[模拟 贪心 优先队列]
- [bzoj1029][JSOI2007]建筑抢修【贪心】【堆】
- bzoj 1029: [JSOI2007]建筑抢修(贪心+优先队列)
- bzoj 1029: [JSOI2007]建筑抢修 贪心+堆
- [BZOJ1029][JSOI2007]建筑抢修-堆-贪心
- 【BZOJ】1029: [JSOI2007]建筑抢修(贪心)
- bzoj 1029: [JSOI2007]建筑抢修【贪心+堆】
- 【BZOJ】1029 [JSOI2007]建筑抢修 贪心+堆
- BZOJ 1029: [JSOI2007]建筑抢修 贪心
- BZOJ 1029: [JSOI2007]建筑抢修【优先队列+贪心策略】
- 【bzoj1029】[JSOI2007]建筑抢修 贪心+堆
- BZOJ_1029_[JSOI2007]_建筑抢修_(贪心+优先队列)
- [BZOJ 1029] [JSOI2007] 建筑抢修 【贪心】
- BZOJ 1029 JSOI2007 建筑抢修 贪心+堆
- BZOJ 1029: [JSOI2007]建筑抢修 堆,贪心,排序
- BZOJ 1029: [JSOI2007]建筑抢修(贪心)
- BZOJ 1029 [JSOI2007]建筑抢修 贪心
- [BZOJ1029] [JSOI2007]建筑抢修(贪心 + 优先队列)