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;
 }
A.cpp

相关文章:

  • 2022-02-17
  • 2021-09-30
  • 2021-07-06
  • 2021-09-11
  • 2021-05-19
  • 2021-08-01
  • 2021-06-08
  • 2021-06-21
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案