P3545
题面
题意
题目中给出两个数组
做法
我们先尽可能满足所有我们遇到的顾客,并且使用一个大根堆存放所有你当前满足过的顾客的信息。当我们遇到一个我们无法直接满足的顾客,如果大根堆的堆顶的
算法正确性证明
由于我们前提条件中有“大根堆堆顶的
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=250005;
typedef pair<long long,int> pii;
long long a[maxn],b[maxn];
bool vis[maxn];//记录是否满足每一位顾客
priority_queue<pii,vector<pii>,less<pii> > que;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",a+i);
for(int i=1;i<=n;i++) scanf("%lld",b+i);
long long tot=0,cnt=0;
for(int i=1;i<=n;i++)
{
tot+=a[i];
if(tot<b[i]&&!que.empty()&&que.top().first>b[i])
{//若无法满足当前顾客并且堆顶更贵的情况
vis[que.top().second]=false;
tot+=que.top().first;//删除堆顶
que.pop();
cnt--;
}
if(tot>=b[i])
{
tot-=b[i];
que.push((pii){b[i],i});
vis[i]=true;//加入当前点
cnt++;
}
}
printf("%lld\n",cnt);
for(int i=1;i<=n;i++)
if(vis[i]) printf("%d ",i);
puts("");
return 0;
}