钓鱼式的贪心(张老师的钓鱼真是万金油)
用堆维护还没走完的楼层
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
int n,tot;
ll Time,m,ans,s;
int h[1000005],v[1000005],w[1000005];
struct ty
{
int v,h,id;
}heap[1000005];
void down(int id)
{
while(id*2<=tot)
{
int j;
if(id*2+1>tot||heap[id*2+1].v<heap[id*2].v) j=id*2; else j=id*2+1;
if(heap[id].v<heap[j].v)
{
swap(heap[id],heap[j]);
id=j;
}
else break;
}
}
void up(int id)
{
while(id/2>=1)
{
if(heap[id].v>heap[id/2].v)
{
swap(heap[id],heap[id/2]);
id=id/2;
}
else break;
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&h[i],&v[i]);
s=s+v[i];
w[i]=1;
if(h[i]>1)
{
tot++;
heap[tot].v=v[i];
heap[tot].h=h[i]-1;
heap[tot].id=i;
up(tot);
}
}
Time=m-(n-1);
for(int i=n;i>=1;i--)
{
if(i+1<=n)
{
Time=Time+w[i+1]; //后面那幢楼已经去不了了,把花在那幢楼的时间加上
s=s-(ll)(w[i+1])*v[i+1]; //收益减去
}
while(Time>0&&tot>0)
{
while(tot>0&&heap[1].id>i)
{
swap(heap[1],heap[tot]);
tot--;
down(1);
}
if(tot==0) break;
if(Time>=heap[1].h)
{
Time-=heap[1].h;
w[heap[1].id]+=heap[1].h;
s=s+(ll)(heap[1].v)*heap[1].h;
swap(heap[1],heap[tot]);
tot--;
down(1);
}
else
{
w[heap[1].id]+=Time;
s=s+(ll)(heap[1].v)*(Time);
heap[1].h-=Time;
Time=0;
}
}
if(Time==0) ans=max(ans,s);
if(Time>0&&tot==0) ans=max(ans,s);
}
cout<<ans;
return 0;
}

被折叠的 条评论
为什么被折叠?



