【BZOJ1029】[JSOI2007] 建筑抢修(堆优化贪心)

7 篇文章 0 订阅
6 篇文章 0 订阅

点此看题面

大致题意: 有N个受到严重损伤的建筑,对于每个建筑,修好它需要 T 1 T1 T1秒,且必须在 T 2 T2 T2秒之前修完( T 1 T1 T1 T 2 T2 T2不是固定值),问你最多能修好几个建筑。


题解

一看到这题,就能想到一个贪心的做法。

但是,裸贪心显然是不能过的,如果加上一个堆优化,就能够水过此题。

我们可以把修好每个建筑所需的时间放入大根堆中存储。对于每一个建筑,若能在规定时间内修好,则将 a n s ans ans 1 1 1,否则比较修好它所需的时间与堆顶元素的大小,若修好它所需的时间更少,则用其替换堆顶,此时 a n s ans ans不变。


代码
#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define N 150000
using namespace std;
int n;
struct Building
{
	int a,t;
}s[N+5];
priority_queue<int> h;
inline char tc()
{
	static char ff[100000],*A=ff,*B=ff;
	return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
	x=0;char ch;
	while(!isdigit(ch=tc()));
	while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
}
inline void write(int x)
{
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
bool cmp(Building x,Building y)
{
	return x.t<y.t;
}
int main()
{
	register int i;
	for(read(n),i=1;i<=n;++i) read(s[i].a),read(s[i].t);
	sort(s+1,s+n+1,cmp);//将每一个建筑按无法重修的时间从小到大排序
	int tot=0,ans=0;//tot表示当前时间
	for(i=1;i<=n;++i)
	{
		if(s[i].t<tot+s[i].a)//判断时间是否来得及
		{
			if(s[i].a<h.top()) tot-=h.top(),h.pop(),h.push(s[i].a),tot+=s[i].a;//如果来不及,比较其与堆顶元素的大小,若其更小,则弹出堆顶,更新当前时间,并将修好该建筑所需时间加入堆中
		}
		else h.push(s[i].a),tot+=s[i].a,++ans;//如果来得及,ans加1,并将修好该建筑所需时间加入堆中
	}
	return write(ans),0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值