zoukankan      html  css  js  c++  java
  • Debate CodeForces

    Elections in Berland are coming. There are only two candidates — Alice and Bob.

    The main Berland TV channel plans to show political debates. There are nn people who want to take part in the debate as a spectator. Each person is described by their influence and political views. There are four kinds of political views:

    • supporting none of candidates (this kind is denoted as "00"),
    • supporting Alice but not Bob (this kind is denoted as "10"),
    • supporting Bob but not Alice (this kind is denoted as "01"),
    • supporting both candidates (this kind is denoted as "11").

    The direction of the TV channel wants to invite some of these people to the debate. The set of invited spectators should satisfy three conditions:

    • at least half of spectators support Alice (i.e. 2am2⋅a≥m, where aa is number of spectators supporting Alice and mm is the total number of spectators),
    • at least half of spectators support Bob (i.e. 2bm2⋅b≥m, where bb is number of spectators supporting Bob and mm is the total number of spectators),
    • the total influence of spectators is maximal possible.

    Help the TV channel direction to select such non-empty set of spectators, or tell that this is impossible.

    Input

    The first line contains integer nn (1n41051≤n≤4⋅105) — the number of people who want to take part in the debate as a spectator.

    These people are described on the next nn lines. Each line describes a single person and contains the string sisi and integer aiai separated by space (1ai50001≤ai≤5000), where sisi denotes person's political views (possible values — "00", "10", "01", "11") and aiai — the influence of the ii-th person.

    Output

    Print a single integer — maximal possible total influence of a set of spectators so that at least half of them support Alice and at least half of them support Bob. If it is impossible print 0 instead.

    Examples

    Input
    6
    11 6
    10 4
    01 3
    00 3
    00 7
    00 9
    Output
    22
    Input
    5
    11 1
    01 1
    00 100
    10 1
    01 1
    Output
    103
    Input
    6
    11 19
    10 22
    00 18
    00 29
    11 29
    10 28
    Output
    105
    Input
    3
    00 5000
    00 5000
    00 5000
    Output
    0

    Note

    In the first example 44 spectators can be invited to maximize total influence: 11, 22, 33 and 66. Their political views are: "11", "10", "01" and "00". So in total 22 out of 44 spectators support Alice and 22 out of 44 spectators support Bob. The total influence is 6+4+3+9=226+4+3+9=22.

    In the second example the direction can select all the people except the 55-th person.

    In the third example the direction can select people with indices: 11, 44, 55 and 66.

    In the fourth example it is impossible to select any non-empty set of spectators.

    题意:

    有四种投票立场的人,分别是 11 , 10 ,01 ,00,

    11代表这个人对a和b都赞同,10代表赞同a,不赞同b,01代表不赞同a,赞同b。00表示都不赞同。

    而每一个人又有一个影响力,

    现在要你从给出的人中选出一些人,使之在满足投票a和投票b的票数占总人数的一半,即2*num(a或b)>=sum_num,全部选择的人的影响力的sum和是尽可能的大。

    思路:

    贪心策略。

    我们容易知道,选择11类型的一定是百利无一害的,那么我们把11类型的所有人都全选。

    我们记a的票数是cnta,b的票数是cntb,选择的总人数是sum。

    那么全选择了11类型的人之后,cnta=cntb=sum,。

    然后我们分析一下选择10和01的人对票数的影响。

    假设我们已经选了2个11类型的人,

    cnta=cntb=sum=2

    然后如果选择一个01的人和一个10的人

    cnta=cntb=3,sum=4

    再来两个

    cnta=cntb=4,sum=6

    再来

    cnta=cntb=5,sum=8

    再来

    cnta=cntb=6,sum=10

    显然这是一个无限接近于1:2的比例关系,但是不会小于1:2,那么就说无论咋取都是满足条件。

    而我们如果只选择01和10的人呢?

    如果当前是cnta=cntb=2,sum=2,

    我们只选择01一个

    cnta=2,cntb=3,sum=3,

    两个

    cnta=2,cntb=4,sum=4,

    三个

    cnta=2,cntb=5,sum=5,

    显然这个已经不满足条件了。

    再来看看我们如果只选择00的

    一个

    cnta=2,cntb=2,sum=3,

    两个

    cnta=2,cntb=2,sum=4,

    三个

    cnta=2,cntb=2,sum=5,

    显然也不满足条件了。

    我们是否发现了什么规律呢?

    如果不是同时选10和01各取一个,而是只单选01或者10中的任意一个,对接近不满足条件的贡献是和00一样的,

    因为当a和b只需要一个不满足条件,整体就不满足条件了,那么10单一起和00就是一样的了,

    那么回到我们的所求,

    求的是让影响力最大,那么我们只需要把11的全选,01和10尽量大的各选取尽量多的之后,把01或者10还剩下的部分和00放在一个,

    然后从剩余部分选择最大影响力的人,直至不符合条件。

    细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    inline void getInt(int* p);
    const int maxn=1000010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int n;
    pii temp;
    struct cmp
    {
        bool operator()(const pii p1,const pii p2)
        {
            return p1.se<p2.second;
        }
    };
    priority_queue<pii,std::vector<pii>,cmp > heap[20];
    int main()
    {
        //freopen("D:\common_text\code_stream\in.txt","r",stdin);
        //freopen("D:\common_text\code_stream\out.txt","w",stdout);
        gbtb;
        cin>>n;
        repd(i,1,n)
        {
            cin>>temp.fi>>temp.se;
            heap[temp.fi].push(temp);
        }
        ll ans=0ll;
        ll l=0ll;
        ll r=0ll;
        ll sum=0ll;
        while(!heap[11].empty())
        {
            ans+=heap[11].top().se;
            sum+=1ll;
            r+=1ll;
            l+=1ll;
            heap[11].pop();
        }
        while(2*(l+1)>=(sum+2)&&(2*(r+1))>=(sum+2)&&(!heap[10].empty())&&(!heap[1].empty()))
        {
            ans+=heap[10].top().se;
            ans+=heap[1].top().se;
            sum+=2ll;
            r+=1ll;
            l+=1ll;
            heap[10].pop();
            heap[1].pop();
        }
        while(!heap[10].empty())
        {
            heap[0].push(heap[10].top());
            heap[10].pop();
        }
        while(!heap[1].empty())
        {
            heap[0].push(heap[1].top());
            heap[1].pop();
        }
        while(2ll*l>=(sum+1)&&2ll*r>=(sum+1)&&(!heap[0].empty()))
        {
            ans+=heap[0].top().se;
            heap[0].pop();
            sum++;
        }
        cout<<ans<<endl;
    
    
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    Nancy学习
    微信公众号开发开发问题记-code been used
    C#——委托、Lambda表达式、闭包和内存泄漏
    【协作式原创】查漏补缺之Go的slice基础和几个难点
    【协作式原创】自己动手写docker之run代码解析
    【算法】剑指第二版3.数组中重复数字
    剑指offer第二版速查表
    【协作式原创】查漏补缺之乐观锁与悲观锁TODO
    【协作式原创】查漏补缺之Go并发问题(单核多核)
    【协作式原创】查漏补缺之Golang中mutex源码实现(预备知识)
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10745561.html
Copyright © 2011-2022 走看看