[BZOJ1029]JSOI2007 建筑抢修|贪心|堆

显然是贪心嘛,就是线段覆盖的强化版。。先按deadline升序排序,将每个建筑依次加入。设sum是当前用掉的时间,如果直接将i加进来是可以的也就是sum+time[i]<=deadline[i],那就直接加,否则查询前面加进来的点中时间最大的j,如果time[i]<time[j],就把j删去加入i。最大时间用一个堆维护即可。

#include<iostream>
#include<cstdio>
#include<memory.h>
#include<algorithm>
#define maxn 150005
using namespace std;
struct building{
	int len,t;
} a[maxn];
bool cmp(building a,building b){return a.t==b.t?a.len<b.len:a.t<b.t;}
int n,i,sum=0,nd=0,ans=0,heap[maxn*4];
void ins(int k)
{
	heap[++nd]=k;
	int i=nd;
	while (i>1&&heap[i]>heap[i/2]) swap(heap[i],heap[i/2]),i/=2;
}
void del()
{
	heap[1]=heap[nd--];
	int i=1;
	while (i<nd&&(heap[i*2]>heap[i]||heap[i*2+1]>heap[i]))
		if (!heap[i*2+1]||heap[i*2]>heap[i*2+1]) swap(heap[i],heap[i*2]),i*=2; else swap(heap[i],heap[i*2+1]),i=2*i+1;
}
int main()
{
	freopen("1029.in","r",stdin);
	scanf("%d",&n);
	for (i=1;i<=n;i++)	scanf("%d%d",&a[i].len,&a[i].t);
	sort(a+1,a+1+n,cmp);memset(heap,0,sizeof(heap));
	for (i=1;i<=n;i++)
		if (sum+a[i].len<=a[i].t) ins(a[i].len),sum+=a[i].len,ans++;
		else if (a[i].len<heap[1]) sum-=heap[1]-a[i].len,del(),ins(a[i].len);
	cout<<ans;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值