• CF1070F Debate


    原题

    Solution

    考虑贪心。

    那么 (s_i=11) 的肯定都选,因为这样不会使答案变劣

    重点就是 (10,01,00) 之间怎么选

    首先, (00) 肯定是最劣的,所以先考虑 (01,10)

    有一个结论是:在最优情况, (s_i=01) 全部选出,或者 (s_i=10) 全部选出

    证明:设现在选了 (x)(01) 的, (y)(10) 的,那么再选 (min(x,y))(01)(10) 显然是不会超过限制的。

    按照 (s_i=10) 全部选择,然后考虑剩下的 (01,00)

    因为要最大,即贪心。所以要按照 (a_i) 排序,然后枚举 (s_i=01) 的选择个数 (j)

    (num_{11}+j<num_{10}) 即支持Bob的人太少,或 (num_{11}+num_{10}<j) 即支持Alice的人太少,就跳过这个 (j)

    那么剩下的可选的就只有 (s_i=00) 的,数量为 (min{num_{00},num_{11}+j-num_{10},num_{11}+num_{10}-j})

    其中第一个是 (s_i=00) 初始数量,第二个是最多还有多少人能不支持Bob,第三个是最多还有多少人能不支持Alice

    (s_i=01) 同理即可

    而枚举时候的价值可以拿前缀和优化,达到 (O(nlog n)) 的时间复杂度。

    Code

    #include<bits/stdc++.h>
    
    using namespace std;
    const int N=4e5+10;
    int n,num[5],a[5][N],cnt,sum,ans;
    
    inline bool cmp(const int &a,const int &b){
        return a>b;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1,x,y;i<=n;i++){
            scanf("%d%d",&x,&y);
            if(!x) a[0][++num[0]]=y;
            else if(x==1) a[1][++num[1]]=y;
            else if(x==10) a[2][++num[2]]=y;
            else a[3][++num[3]]=y,sum+=y;
        }
        sort(a[0]+1,a[0]+num[0]+1,cmp);
        sort(a[1]+1,a[1]+num[1]+1,cmp);
        sort(a[2]+1,a[2]+num[2]+1,cmp);
        for(int i=2;i<=num[0];i++) a[0][i]+=a[0][i-1];
        for(int i=2;i<=num[1];i++) a[1][i]+=a[1][i-1];
        for(int i=2;i<=num[2];i++) a[2][i]+=a[2][i-1];
        for(int i=0;i<=num[1];i++){
            if(num[3]+i<num[2]||num[3]+num[2]<i) continue;
            ans=max(ans,a[1][i]+a[2][num[2]]+a[0][min(num[0],min(num[3]+i-num[2],num[3]+num[2]-i))]);
        }
        for(int i=0;i<=num[2];i++){
            if(num[3]+i<num[1]||num[3]+num[1]<i) continue;
            ans=max(ans,a[2][i]+a[1][num[1]]+a[0][min(num[0],min(num[3]+i-num[1],num[3]+num[1]-i))]);
        }
        printf("%d
    ",ans+sum);
        return 0;
    }
    

    我这里把 (00,01,10,11) 看作二进制了,心领神会吧(o゚v゚)ノ

  • 相关阅读:
    VS 2008潜在强大的功能:提取EXE文件中的ICO等资源
    园友们注意:淘宝网上QQ会员 4钻 3元 等都为骗子行为
    Comet Async Process Request Handler
    WCF(Sender) to MSMQ to WCF(Receiver)
    ASP.NET Web Form GridView DetailsView Query Edit
    WCF NetTcp AsyncQueue Service
    Xml CDATA 序列化
    Sync Invoke Remoting Async Invoke
    .Net 4.0 Remoting ConcurrentQueue
    Socket Async Receive Data to LinkedList Buffer (telnet proxy server)
  • 原文地址:https://www.cnblogs.com/jasony/p/13872513.html
Copyright © 2020-2023  润新知