您的位置:首页 > 其它

洛谷P3129 [USACO15DEC]高低卡(白金)High Card Low Card (Platinum)

2017-09-13 21:59 459 查看
https://daniu.luogu.org/problem/show?pid=3129

很好的一道题目

题解:

这道贪心还真的有点把我6到了。。。

如果按照田忌赛马的逻辑之类的

很容易想到 要大的赢得时候 选一个刚好比他大一点的就好 小的时候同理 选一个刚好小一点的

那么我们用set前后搞一下 front[i]就是大的赢 1到i赢最多的盘数 behind[i]同理 从后往前 n到i 小的赢

答案就max(f[i]+g[i+1]) 然而我知道你想问我选重复怎么办?

这里有个证明: 如果有一个数a用了两次 那么假设没用的那个数b < a 那么在较小赢时候可以替换a 反之亦然

刷访问量走起…http://blog.csdn.net/cgh_andy/article/details/53011315;

真的很牛逼,我当然想到了可以通过前后缀数组做,但是重复的现象是必然的,没想到尽然是不影响的;

真的是太菜了

#include<bits/stdc++.h>
#define Ll long long
using namespace std;
const int N=1e5+5;
int a
,f
,F
,fa
,Fa
;
int n,m,ans;
int get1(int x){return fa[x]==-1?x:fa[x]=get1(fa[x]);}
int get2(int x){return Fa[x]==-1?x:Fa[x]=get2(Fa[x]);}
int main()
{
scanf("%d",&n);
memset(fa,-1,sizeof fa);
memset(Fa,-1,sizeof Fa);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
fa[a[i]]=a[i]+1;
Fa[a[i]]=a[i]-1;
}
for(int i=1;i<=n;i++){
f[i]=f[i-1];
int x=get1(a[i]+1);
if(x==n*2+1)x==get1(1);
if(x==n*2+1)continue;
if(x>a[i])f[i]++;
fa[x]=get1(x+1);
}
for(int i=n;i>=1;i--){
F[i]=F[i+1];
int x=get2(a[i]-1);
if(x==0)x==get2(n);
if(x==0)continue;
if(x<a[i])F[i]++;
Fa[x]=get2(x-1);
}
for(int i=0;i<=n;i++)ans=max(ans,f[i]+F[i+1]);
printf("%d",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: