您的位置:首页 > Web前端 > JavaScript

【贪心+堆】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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: