题解 辩论 贪心

题解 辩论

题目描述

在这里插入图片描述

具体做法与心路历程

看到这道题我秒想了网络流,搞了下没出来,发现是个简单的贪心,不难想。

具体做法

A , B A,B A,B表示支持议题 1 1 1的人数和支持议题 2 2 2的人数,没选一个就把对应的 + 1 , − 1 +1,-1 +1,1

  • 如果态度为 11 11 11,那么可以贪心的全选了。
  • 如果 A , B > 0 A,B>0 A,B>0,那么 01 , 10 01,10 01,10各选一个后 A , B A,B A,B不变,所以每次贪心选最大的 01 , 10 01,10 01,10各一个。
  • 10 , 01 10,01 10,01某个不够时,相当于最多只能再选 m i n ( A , B ) min(A,B) min(A,B)个了,贪心在剩下的选最大即可

C o d e \mathcal{Code} Code

/*******************************
Author:galaxy yr
LANG:C++
Created Time:2019年10月24日 星期四 08时07分28秒
*******************************/
#include<cstdio>
#include<algorithm>
#include<queue>

using namespace std;

struct IO{
    template<typename T>
    IO & operator>>(T&res)
    {
        T q=1;char ch;
        while((ch=getchar())<'0' or ch>'9')if(ch=='-')q=-q;
        res=(ch^48);
        while((ch=getchar())>='0' and ch<='9') res=(res<<1)+(res<<3)+(ch^48);
        res*=q;
        return *this;
    }
}cin;

int n,a,A,B;
long long ans;
priority_queue<int>X,Y,Z;
//(-1,-1),(1,-1),(-1,1)


bool check()
{
    if(!A && !B) return false;
    if(X.empty() && Y.empty() && Z.empty())
        return false;
    if(Y.empty() && !A)
        return false;
    if(Z.empty() && !B)
        return false;
    return true;
}

void solve()
{
    if(!A)
    {
        ans+=Y.top();
        Y.pop();
        A++,B--;
        return;
    }
    if(!B)
    {
        ans+=Z.top();
        Z.pop();
        A--,B++;
        return;
    }
    if(A>0 && B>0 && !Y.empty() && !Z.empty())
    {
        ans+=Y.top()+Z.top();
        Y.pop(),Z.pop();
        return;
    }
    A--,B--;
    if(Y.empty() && Z.empty())
    {
        ans+=X.top(),X.pop();
        return;
    }
    if(Y.empty())
    {
        if(X.empty() || X.top()<Z.top())
            ans+=Z.top(),Z.pop();
        else
            ans+=X.top(),X.pop();
        return;
    }
    if(Z.empty())
    {
        if(X.empty() || X.top()<Y.top())
            ans+=Y.top(),Y.pop();
        else
            ans+=X.top(),X.pop();
        return;
    }

}

int main()
{
    //freopen("debate.in","r",stdin);
    //freopen("debate.out","w",stdout);
    cin>>n;
    int ch;
    for(int i=1;i<=n;i++)
    {
        cin>>ch>>a;
        if(ch==11)
            A++,B++,ans+=a;
        if(ch==0)
            X.push(a);
        if(ch==10)
            Y.push(a);
        if(ch==1)
            Z.push(a);
    }
    while(true)
    {
        if(!check())break;
        solve();
    }
    printf("%lld\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值