Debate (Codeforces 1070F)
阿新 • • 發佈:2018-11-11
題目連結: http://codeforces.com/contest/1070/problem/F
思路: 先把11的選上,然後01和10的選min(投01和10的人的個數),最後計算是否還可以再選入,然後從剩下的人當中選擇影響力大的。
#include<cstdio> #include<iostream> #include<cstring> #include <algorithm> using namespace std; typedef long long LL; const int MAXN = 1e6; struct A { int a,b=0; //這裡可以用int型儲存,比較方便 }s10[MAXN],s01[MAXN],s00[MAXN]; bool cmp(A x,A y) { return x.b>y.b; } int main() { int n,ans=0; cin>>n; int e11=0,e10=0,e01=0,e00=0; for(int i=0;i<n;i++) { int x,y; cin>>x>>y; if(x==11){ ans+=y;e11++; //投11的人一定會被選上,所以只需要記下影響力和人數就可以了 } if(x==10){ s10[e10].a=x;s10[e10].b=y;e10++; } if(x==1){ s01[e01].a=x;s01[e01].b=y;e01++; } if(x==0){ s00[e00].a=x;s00[e00].b=y;e00++; } } sort(s10,s10+e10,cmp); //先對s01和s10按影響力從大到小排序 sort(s01,s01+e01,cmp); int minn=min(e01,e10); for(int i=0;i<minn;i++) { ans+=s10[i].b+s01[i].b; } int all=(e11+minn)*2; //計算可以選上的總人數 int k=all-e11-minn*2; //k為還可以選的人數 if(e10>e01) { for(int i=minn;i<e10;i++) //把s01或者s10中剩餘的人數加到s00中,方便排序 s00[e00++]=s10[i]; } else { for(int i=minn;i<e01;i++) s00[e00++]=s01[i]; } sort(s00,s00+e00,cmp); //此時s00中還存有s10或s01中剩餘的人,然後排序 for(int i=0;i<k;i++) { ans+=s00[i].b; //不需要考慮怎麼投的票了,只需要選擇影響力大的就可以了 } cout<<ans<<endl; return 0; }