题解:
很明显,区间DP。
若单纯二维,无法实现复杂的区间合并。所以我们考虑三维。
f
[
i
]
[
j
]
[
k
]
f[i][j][k]
f[i][j][k]表示
[
i
,
j
]
[i,j]
[i,j]区间连带
j
j
j右边
k
k
k个相同一起消掉的
M
a
x
Max
Max。
在区间合并更新最大值时强制让一段区间单独消完,比如右子区间。
但这时不知道最优决策,所以采用动态规划便利所有状态的特性,挨个尝试。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define N 205
using namespace std;
int f[N][N][N],n,sum[N],a[N];
int main(){
int t;cin>>t;int num=t;
while(t--){
scanf("%d",&n);
memset(sum,0,sizeof(sum));
memset(f,0,sizeof(f));
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
for(int i=1;i<=n;++i){
for(int j=i+1;j<=n;++j){
if(a[i]==a[j])sum[i]++;
}
}
for(int i=n;i;--i){
for(int j=i;j<=n;++j){
for(int k=0;k<=sum[j];++k){
f[i][j][k]=max(f[i][j][k],f[i][j-1][0]+(k+1)*(k+1));
for(int p=i;p<j;++p){
if(a[p]==a[j]){
f[i][j][k]=max(f[i][j][k],f[i][p][k+1]+f[p+1][j-1][0]);
}
}
}
}
}
printf("Case %d: %d\n",num-t,f[1][n][0]);
}
return 0;
}