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; }
标签:Usaco2015,set,iterator,int,100100,bound,High,Card,pl 来源: https://www.cnblogs.com/yzxverygood/p/10357519.html