Codeforces Round #804 (Div. 2) C D

C 1700
D 2300
所以 我并没有做水题。

考虑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;
}
posted @ 2022-11-23 21:16  chdy  阅读(19)  评论(0编辑  收藏  举报