[USACO15DEC]High Card Low Card (Platinum)

Posted yanshannan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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;
}





以上是关于[USACO15DEC]High Card Low Card (Platinum)的主要内容,如果未能解决你的问题,请参考以下文章

P3128 [USACO15DEC]最大流Max Flow

洛谷 P3128 [USACO15DEC]最大流Max Flow

洛谷 P3128 [USACO15DEC]最大流Max Flow

P3130 [USACO15DEC]计数haybalesCounting Haybales

[USACO15DEC]最大流Max Flow

[Luogu 3128] USACO15DEC Max Flow