UVA10559 Blocks

玄学东西,毒瘤状态,死也想不出

设f[l][r][i]表示[l,r]区间,右边再加上i个颜色和r颜色相同的块,消掉这些的最大收益

两种转移方式:

  • 把r和后面i个一起销毁,\(f[l][r-1][0]+(i+1)^2\)
  • 选择一个位置p使得p,r位置上的颜色相同,消掉p,r中间这段,再把r和后面i个接上去转移。\(f[l][p][i+1]+f[p+1][r-1]\)

我™怎么知道为什么

#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il int gi(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
int f[201][201][201];
int a[201];
int main(){
	int T=gi();
	for(int yyb=1;yyb<=T;++yyb){
		int n=gi();
		for(int i=1;i<=n;++i)a[i]=gi();
		for(int i=1;i<=n;++i)
			for(int j=0;j<=n;++j)
				f[i][i][j]=(j+1)*(j+1);
		for(int s=2;s<=n;++s)
			for(int l=n-s+1;l;--l){
				int r=l+s-1;
				for(int i=0;i<=n;++i){
					f[l][r][i]=f[l][r-1][0]+(i+1)*(i+1);
					for(int p=l;p<r;++p)if(a[p]==a[r])f[l][r][i]=std::max(f[l][r][i],f[l][p][i+1]+f[p+1][r-1][0]);
				}
			}
		printf("Case %d: %d\n",yyb,f[1][n][0]);
	}
	return 0;
}
posted @ 2018-09-18 13:10  菜狗xzz  阅读(218)  评论(0编辑  收藏  举报