BZOJ 1029 JSOI2007 建筑抢修 贪心+堆

本文介绍了一种解决最大化建筑抢修数量问题的贪心算法。通过优化贪心策略,确保在给定时间内完成尽可能多的建筑抢修。详细阐述了算法的实现过程,包括使用大根堆来辅助决策,以及如何通过调整算法逻辑提高效率。实例分析展示了算法的有效性和实际应用价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:n个建筑需要抢修,第i个建筑需要T1时间抢修,必须在T2时间之前抢修完毕,求最多能抢修多少建筑

首先我们对T2排序 然后依次修理 但是这样贪心显然是不正确的 比如说这组数据:

5
10 10
10 20
2 21
2 21
2 21

贪心只能修理前两个,而实际上最多可以修理4个

于是我们考虑修正贪心算法

比如说这组数据,当我们枚举到3的时候,虽然已经无法修理更多了,但是我们可以取消修理建筑1而改修理3,这样虽然不能更新ans 但是可以为后面的建筑节省时间

所以做法就很明确了

我们维护一个大根堆 每修理一栋建筑 我们就把这栋建筑的T1值加入堆 若当前无法修理 我们判断堆顶是否比这栋建筑的T1大 如果大 取消修理堆顶,改为修理当前建筑

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 150100
using namespace std;
struct construction{
	int T1,T2;
	bool operator < (const construction &x) const
	{
		return T2 < x.T2;
	}
}buildings[M];
int n,ans,now,heap[M],top;
void Insert(int x)
{
	heap[++top]=x;
	int t=top;
	while(t>1&&heap[t]>heap[t>>1])
		swap(heap[t],heap[t>>1]),t>>=1;
}
void Pop()
{
	heap[1]=heap[top--];
	int t=2;
	while(t<=top)
	{
		if(t<top&&heap[t+1]>heap[t])
			++t;
		if(heap[t]>heap[t>>1])
			swap(heap[t],heap[t>>1]),t<<=1;
		else
			break;
	}
}
int main()
{
	int i;
	cin>>n;
	for(i=1;i<=n;i++)
		scanf("%d%d",&buildings[i].T1,&buildings[i].T2);
	sort(buildings+1,buildings+n+1);
	for(i=1;i<=n;i++)
	{
		if(now+buildings[i].T1<=buildings[i].T2)
		{
			now+=buildings[i].T1;
			++ans;
			Insert(buildings[i].T1);
		}
		else
		{
			if(!top)
				continue;
			int temp=heap[1];
			if( temp>buildings[i].T1 )
				now=now+buildings[i].T1-temp,Pop(),Insert(buildings[i].T1);
		}
	}
	cout<<ans<<endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值