Task 1 辩论
有N 个参加辩论的候选人,每个人对这两个议题都有明确的态度,支持或反对。
作为组织者,小D 认真研究了每个候选人,并给每个人评估了一个非负的活跃度,
他想让活跃度之和尽可能大。
选出的候选人必须满足以下两个条件:
1. 至少有一半的人支持议题1。
2. 至少有一半的人支持议题2。
小D 想知道,在满足以上两个条件的情况下,活跃度之和最大是多少。对于$ 100\%$ 的数据,$ N \leq 4 \times 10^5,0 ≤ Ai ≤ 5 \times 10^3 $
Sol : 首先$11$的全部都可以选,然后将$01$ 和 $10$排序,依次选取,把一组最大的$10$和$10$当做$11$处理,
剩余的情况就是$10$或$01$ $00$,这样子显然会让一个数逐渐的趋向于小于Sum/2,所以这个时候直接就挑权值大的数找即可。
复杂度是$O(n \ log_2 \ n)$
# include<bits/stdc++.h> # define int long long using namespace std; vector<int>a1,a2,a3,a4,tmp; int n; signed main() { scanf("%lld",&n); for (int i=1;i<=n;i++) { int op,v; scanf("%lld%lld",&op,&v); if (op==11) a1.push_back(v); else if (op==10) a2.push_back(v); else if (op==01) a3.push_back(v); else if (op==00) a4.push_back(v); } sort(a1.begin(),a1.end()); reverse(a1.begin(),a1.end()); sort(a2.begin(),a2.end()); reverse(a2.begin(),a2.end()); sort(a3.begin(),a3.end()); reverse(a3.begin(),a3.end()); int num=0,ans=0,all=0; for (int i=0;i<a1.size();i++) num++,ans+=a1[i],all++; int pos; for (pos=0;pos<min(a2.size(),a3.size());pos++) { ans+=a2[pos]+a3[pos]; num++; all+=2; } for (int i=pos;i<a2.size();i++) tmp.push_back(a2[i]); for (int i=pos;i<a3.size();i++) tmp.push_back(a3[i]); for (int i=0;i<a4.size();i++) tmp.push_back(a4[i]); sort(tmp.begin(),tmp.end()); reverse(tmp.begin(),tmp.end()); for (int i=0;i<tmp.size();i++) { if (2*num>=all+1) ans+=tmp[i],all++; else break; } printf("%lld\n",ans); return 0; }