【BZOJ】1029 [JSOI2007]建筑抢修 贪心+堆

题目传送门

今天的时间好少啊,晚自修还要去听专题报告,都没有时间刷题了,只有打一道水题练练手了。

这题的解题思路是贪心,对每个节点的T2进行排序,然后从小到大修最多的建筑就行了。

但是这个贪心的思路是有问题的:如果T2最小的节点i的T1很大,但是在i的T2范围内有许多节点的T1很小,不就GG了?

所以我们可以用一个堆来维护当前维修的所有建筑的T1,然后枚举下一个节点,若这个节点可以直接维修就修,若不能就判断这个节点的T1值是否比当前的堆顶小,若比堆顶小,就用当前的节点来替换堆顶的节点,也就是为之后的节点空出更多的时间。

因为博主比较懒,所以就打了一个priority_queue,这样比较节省代码。

附上AC代码:

#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;

struct note{
	int t,w;
	bool operator < (const note lyf) const {
		return t<lyf.t;
	}
}a[150010];
priority_queue <int> que;
int n,now,ans;

int main(void){
	scanf("%d",&n);
	for (int i=1; i<=n; ++i) scanf("%d%d",&a[i].w,&a[i].t);
	sort(a+1,a+1+n);
	for (int i=1; i<=n; ++i)
		if (now+a[i].w<=a[i].t) now+=a[i].w,++ans,que.push(a[i].w);
			else if (!que.empty()&&a[i].w<que.top()) now+=a[i].w-que.top(),que.pop(),que.push(a[i].w);
	printf("%d",ans);
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值