Codeforces Round #503 (by SIS, Div. 2) C. Elections (枚举)

-
题意:有\(m\)个党派,\(n\)个选民,每个选民都有自己要投的党派,你是党派1的首领,富可敌国,你想要贿赂一些选民使得所有党派中,你的票数最高,问最少要花多少钱才能当选.
-
题解:像这种贪心怎么想都想不出来的题的话,就应该考虑枚举和二分了,我们可以枚举我需要的票数来写,假设我们最终当选的票数为\(k\),那么其他所有党派的票数都应该小于\(k\),每次枚举维护答案即可.
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} vector<PII> p,v[N]; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int n,m; cin>>n>>m; int cnt=0; rep(i,1,n){ int id,w; cin>>id>>w; if(id==1) {cnt++;continue;} p.pb(make_pair(w,i)); v[id].pb(make_pair(w,i)); } sort(p.begin(),p.end()); rep(i,1,m) sort(v[i].begin(),v[i].end()); ll ans=1e18; rep(k,1,n){ ll sum=0; vector<bool> st(n+1); int res=0; rep(i,2,m){ int cur=0; while(v[i].size()-cur>=k){ sum+=v[i][cur].fi; st[v[i][cur].se]=true; cur++; } res+=cur; } int pos=0; while(res+cnt<k){ if(!st[p[pos].se]){ sum+=p[pos].fi; st[p[pos].se]=true; res++; } pos++; } ans=min(ans,sum); } cout<<ans<<'\n'; return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号