Description
给你一堆块,每个块有颜色,每次可以消去相邻颜色块,并获得块大小平方的分数,求最高得分.
Sol
DP/记忆化搜索.
(f[i][j][k]) 表示 ((i,j)) 这个区间并且 (j) 后面有 (k) 个与它颜色相同的块,枚举断点,区间DP.
Code
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int N = 205; #define sqr(x) ((x)*(x)) int T,n; int a[N],f[N][N][N]; inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar(); while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; } int DFS(int l,int r,int k){ if(l>r) return 0; if(f[l][r][k]) return f[l][r][k]; f[l][r][k]=DFS(l,r-1,0)+sqr(k+1); for(int i=l;i<r;i++) if(a[i]==a[r]) f[l][r][k]=max(f[l][r][k],DFS(l,i,k+1)+DFS(i+1,r-1,0)); return f[l][r][k]; } int main(){ T=in(); for(int t=1;t<=T;t++){ n=in();for(int i=1;i<=n;i++) a[i]=in(); memset(f,0,sizeof(f)); printf("Case %d: %d ",t,DFS(1,n,0)); }return 0; }