zoukankan      html  css  js  c++  java
  • [USACO15DEC]High Card Low Card (Platinum)

    https://www.zybuluo.com/ysner/note/1300791

    题面

    贝西和她的朋友艾尔西正在玩这个简单的纸牌游戏。游戏有(2N)张牌,牌上的数字是(1)(2N)。把这些牌分成两份,贝西有(N)张,艾尔西有另外(N)张。接下来她们进行(N)轮出牌,每次各出一张牌。一开始,谁出的牌上的数字大,谁就获得这一轮的胜利。贝西有一个特殊权利,她可以在任意一个时刻把原本数字大的获胜的规则改成数字小的获胜,这个改变将会一直持续到游戏结束。特别的,贝西可以从第一轮开始就使用小牌获胜的规则,也可以直到最后一轮都还不使用大牌获胜的规则。
    现在,贝西已经知道了艾尔西出牌的顺序,她想知道她最多能够赢多少轮。

    解析

    显然前面每次选择比对方大却又尽可能小的牌,后面选择比对方小却又尽可能大的牌。
    其实这就是田径赛马的原理。

    支持删除和二分查找,显然(set)
    然后分别从前后预处理应该出什么牌,最后枚举中介点就行。

    问题出在具体实现上。
    后一个过程其实可以用一个存负值的(set)来搞。
    而不是像蒟蒻一样用一个存正值的(set)然后(TLE)半天。

    还有(lower\_bound)没找到结果会返回(end())

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #define ll long long
    #define fp(i,a,b) for(int i=a;i<=b;++i)
    #define fq(i,a,b) for(int i=a;i>=b;--i)
    using namespace std;
    const int N=5e5+100;
    int n,a[N],q[N],h[N],ans;
    bool vis[N];
    set<int>S1,S2;
    set<int>::iterator it;
    int main()
    {
      scanf("%d",&n);
      fp(i,1,n) scanf("%d",&a[i]),vis[a[i]]=1;
      fp(i,1,2*n) if(!vis[i]) S1.insert(i),S2.insert(-i);
      fp(i,1,n)
        {
          it=S1.lower_bound(a[i]);
          if(it!=S1.end())
        {
          q[i]=q[i-1]+1;
          S1.erase(it);
        }
          else q[i]=q[i-1],S1.erase(*S1.begin());
        }
      fq(i,n,1)
        {
          it=S2.lower_bound(-a[i]);
          if(it!=S2.end())
        {
          h[i]=h[i+1]+1;
          S2.erase(it);
        }
          else h[i]=h[i+1],S2.erase(*S2.begin());
        }
      fp(i,0,n) ans=max(ans,q[i]+h[i+1]);
      printf("%d
    ",ans);
      return 0;
    }
    
  • 相关阅读:
    如何增加按钮的点击间隔时间
    如何增加button的点击范围
    定时器Timer的使用
    NSCache
    GCD和NSOperation的区别
    NSOperation实现线程间通信
    NSOperation添加操作依赖和监听
    自定义NSOperation
    NSOperation的多线程
    单例的实现(完整版代码)
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9743977.html
Copyright © 2011-2022 走看看