• bzoj4391 [Usaco2015 dec]High Card Low Card


    传送门

    分析

    神奇的贪心,令f[i]表示前i个每次都出比对方稍微大一点的牌最多能赢几次

    g[i]表示从i-n中每次出比对方稍微小一点的牌最多赢几次

    ans=max(f[i]+g[i+1]) 0<=i<=n

    虽然方案可能会重合但是这是可行的

    1:因为限制比原题目宽,所以ans>=真实的答案

    2:对于重复取的数a,如果集合中有个没取的数<a,那么在用小的赢的时候可以代替a

    如果>a,那么在用大的赢时可以代替a

    用set来记录最接近的数

    代码

    #include<bits/stdc++.h>
    using namespace std;
    set<int>a,b;
    int f[100100],g[100100],is[100100],d[100100]; 
    int main(){
        int n,m,i,j,k;
        scanf("%d",&n);
        for(i=1;i<=n;i++){
          scanf("%d",&d[i]);
          is[d[i]]=1;
        }
        for(i=1;i<=2*n;i++)
          if(!is[i]){
            a.insert(i);
            b.insert(-i);
          }
        for(i=1;i<=n;i++){
          set<int>::iterator pl=a.lower_bound(d[i]);
          if(pl!=a.end())a.erase(pl),f[i]=f[i-1]+1;
            else f[i]=f[i-1];
        }
        for(i=n;i>0;i--){
          set<int>::iterator pl=b.lower_bound(-d[i]);
          if(pl!=b.end())b.erase(pl),g[i]=g[i+1]+1;
            else g[i]=g[i+1];
        }
        int Ans=0;
        for(i=0;i<=n;i++)Ans=max(Ans,f[i]+g[i+1]);
        cout<<Ans<<endl;
        return 0;
    }

    转载于:https://www.cnblogs.com/yzxverygood/p/10357519.html

  • 相关阅读:
    java第一次作业
    第十一次作业
    第十次作业
    第九次作业
    第八次作业
    第七次作业
    第六次作业
    第五次作业
    实验四,实验五
    Java_实验二
  • 原文地址:https://www.cnblogs.com/twodog/p/12135201.html
Copyright © 2020-2023  润新知