正题
好题,去吃晚饭的时候想出来的。
考虑一个构造表示需要i个人才投的人有多少个,用
表示
,那么当
的时候,那么这个位置上的人就可以直接被取走。
否则,前面需要多出来个人才能把这个位置上的人取走,另外,你可以买一些人,也就是说把一个位置为
的人,移到0的位置上需要
代价,一个后缀需要多少个人移到前面就是
,然后贪心取就可以了,用一个堆来维护。
#include<bits/stdc++.h>
using namespace std;
const int N=200010;
int T,n,last[N],bound;
vector<int> V[N];
priority_queue<int,vector<int>,greater<int> > F;
int main(){
scanf("%d",&T);
while(T--){
long long ans=0;
scanf("%d",&n);
for(int i=0;i<n;i++) V[i].clear(),last[i]=0;
int x,d;
for(int i=1;i<=n;i++) scanf("%d %d",&x,&d),V[x].push_back(d);
last[0]=V[0].size();
for(int i=1;i<n;i++) last[i]=last[i-1]+V[i].size();
for(int i=n-1;i>=1;i--) if(last[i-1]<i) last[i]=i-last[i-1];else last[i]=0;last[0]=0;
bound=0;
while(!F.empty()) F.pop();
for(int i=n-1;i>=1;i--) {
for(int j=0;j<V[i].size();j++) F.push(V[i][j]);
if(last[i]>bound){
last[i]-=bound;bound+=last[i];
while(last[i]--) ans+=F.top(),F.pop();
}
}
printf("%I64d\n",ans);
}
}
本文深入探讨了一种算法竞赛中常见的策略问题,通过构建数学模型,分析了不同人员配置下资源的有效利用,提出了一种基于堆的贪心算法,用于解决特定条件下的最优解问题。
862

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



