Codeforces Round #804 (Div. 2) C D
考虑0的位置 一定不动 再考虑1的位置 也不动
考虑2的位置 不妨设0的位置为L 1的位置为R 那么若2的位置在L~R之间那么2就可以随便放了。
若不在则2的位置唯一再更新LR即可 之后不断的继续放就行了。
code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 2000000000
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define sq sqrt
#define y(w) t[w].y
#define x(w) t[w].x
#define z(w) t[w].z
#define id(cc) s[cc].id
#define w(cc) s[cc].w
#define S second
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
using namespace std;
const int MAXN=100010;
int T;
int n;
int a[MAXN],b[MAXN];
int main()
{
//freopen("1.in","r",stdin);
sc(T);
while(T--)
{
sc(n);
rep(1,n,i)
{
sc(a[i]);
b[a[i]]=i;
}
int L=b[0],R=b[1];
if(L>R)swap(L,R);
int ans=1;
rep(2,n-1,i)
{
if(b[i]<L)
{
L=b[i];continue;
}
if(b[i]>R)
{
R=b[i];continue;
}
ans=(ll)ans*(R-L+1-i)%mod;
}
put(ans);
}
}
注意到n只有5000 直接贪心非常难做。考虑dp 容易想到这个序列可以dp出来。
设f[i]表示到达i且i必选的最大值。i之后合法不合法不知道但i之前的那段序列必合法。
这样 枚举了j 那么i-j-1这个区间一定为偶数 a[j]==a[i] 什么时候这个区间完全消完?
最大值小于等于区间一半 递归的可以发现成立。
注意如果\(f_i\)为答案注意检查i+1~n这一段是否合法。
code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 2000000000
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define sq sqrt
#define y(w) t[w].y
#define x(w) t[w].x
#define z(w) t[w].z
#define id(cc) s[cc].id
#define w(cc) s[cc].w
#define S second
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
using namespace std;
const int MAXN=5010;
int T;
int n;
int a[MAXN],b[MAXN];
int f[MAXN];
int main()
{
freopen("1.in","r",stdin);
sc(T);
while(T--)
{
sc(n);
rep(1,n,i)sc(a[i]);
f[0]=0;
rep(1,n,i)
{
f[i]=-1;int mx=0;
for(int j=i-1;j>=0;--j)
{
if(!((i-j-1)&1)&&(a[j]==a[i]||j==0)&&mx<=(i-j-1)/2)
{
if(f[j]!=-1)f[i]=max(f[i],f[j]+1);
}
++b[a[j]];
mx=max(mx,b[a[j]]);
}
for(int j=i-1;j>=0;--j)--b[a[j]];
}
int ans=f[n]==-1?0:f[n],mx=0;
for(int i=n;i>=2;--i)
{
++b[a[i]];
mx=max(mx,b[a[i]]);
if(!((n-i+1)&1)&&mx<=(n-i+1)/2)ans=max(ans,f[i-1]);
}
rep(2,n,i)--b[a[i]];
put(ans);
}
return 0;
}