BZOJ 1029 建筑抢修 贪心(替换)

题意:n个建筑,修理第i个建筑需要a[i]秒 第i个建筑,若在第b[i]秒时还没被修复,则永远无法修复.
n<=1e5,a[i],b[i]<=1e9,问从0秒开始 最多能修复多少个建筑?

贪心:明显先让deadline早的先修,然后排序一下,然后就wa了....
如果当前第i个修不了 但是取消已经修过中消耗时间最大的,然后用当前a[i]来代替.

若第i个变为可行,则维修个数不变 并且当前时间缩短.显然更优,用优先队列维护即可 (好骚的操作.)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;
const int N=2e5+20,inf=0x3f3f3f3f;
int n;
struct node{
	ll a,b;
}c[N];
bool cmp(node a,node b)
{
	return a.b<b.b;
}
priority_queue<ll> q;
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
		scanf("%I64d%I64d",&c[i].a,&c[i].b);
	sort(c+1,c+1+n,cmp);
	ll cur=0,res=0;
	for(int i=1;i<=n;i++)
	{
		if(cur+c[i].a<=c[i].b)
		{
			cur+=c[i].a,res++;
			q.push(c[i].a);
		}
		else
		{
			ll mx=q.top();
			if(mx>c[i].a&&cur-mx+c[i].a<=c[i].b)
			{
				q.pop();
				q.push(c[i].a);
				cur=cur-mx+c[i].a;
			}
		}
	}
	cout<<res<<endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值