标签:efi while c代码 排序 csharp problem mes $1 tin
http://codeforces.com/contest/1251/problem/E2
主角需要获得n个人的投票
有两种方式让某个人投票
1,已经投票的人数大于m
2,花p枚硬币收买
$1\leq n \leq 200 000$
对$m$进行排序
保留前缀的$m$数组,$pre[x]$为$m$小于等于$x$的人数
对x逆序处理,当枚举到$x$的时候,假设$m$小于等于$x-1$的那些人已经投票,也就是有$pre[x-1]$人已经投票
如果$pre[x-1]>=x$那么不需要处理
如果$pre[x-1]<x$那么$m$在$x$到$n$的人至少要收买$x-pre[x-1]$个人
得到所有$x$需要收买的后缀,显然,从后往前处理最优
#include <bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
using namespace std;
const int maxn=2e5+7;
int pre[maxn];
vector<int>ve[maxn];
multiset<int>se;
int main() {
int T,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int a,b;
scanf("%d %d",&a,&b);
pre[a]++;
ve[a].push_back(b);
}
for(int i=1;i<=n;i++)
pre[i]+=pre[i-1];
int cnt=0;
ll ans=0;
for(int i=n;i>=1;i--){
for(int j=0;j<ve[i].size();j++)se.insert(ve[i][j]);
int v=i-cnt-pre[i-1];
while(v>0){
ans+=(*se.begin());
se.erase(se.begin());
v--;
cnt++;
}
}
se.clear();
for(int i=0;i<=n;i++)ve[i].clear(),pre[i]=0;
printf("%lld\n",ans);
}
return 0;
}
codeforces#1251E2. Voting (Hard Version)(贪心)
标签:efi while c代码 排序 csharp problem mes $1 tin
原文地址:https://www.cnblogs.com/carcar/p/11761552.html