Codeforces 458C - Elections
思路:
三分凹形函数极小值域
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e5+5; const int INF=0x7f7f7f7f; vector<int>g[N],vc; int n; int cost(int x){ int need=x-g[0].size(),ans=0; vc.clear(); for(int i=1;i<N;i++){ for(int j=0;j<g[i].size();j++){ if(g[i].size()-j>=x){ need--; ans+=g[i][j]; } else vc.pb(g[i][j]); } } sort(vc.begin(),vc.end()); for(int i=0;i<need;i++)ans+=vc[i]; return ans; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int a,b; cin>>n; for(int i=0;i<n;i++)cin>>a>>b,g[a].pb(b); for(int i=0;i<N;i++)sort(g[i].begin(),g[i].end()); int l=g[0].size(),r=n,m1=(l+l+r)/3,m2=(l+r+r)/3; while(l<r){ if(cost(m1)>cost(m2)){ if(l==m1)break; else l=m1; } else { if(r==m2)break; else r=m2; } m1=(l+l+r)/3; m2=(l+r+r)/3; //cout<<l<<' '<<r<<' '<<m1<<' '<<m2<<endl; } int ans=INF; for(int i=l;i<=r;i++)ans=min(ans,cost(i)); cout<<ans<<endl; return 0; }