思路:
我们先预处理颜色相同且连续的为一个颜色块的长度和颜色
设f[i][j][k]表示删除i到j,后面跟着有k个和j相同颜色的木块的最大分
则设一个中转点l使l和j的颜色相同,则
f[i][j][k]=f[i][l][k+len[r]]+f[i+1][r-1][0](先把l到j之间的方块消除)
c o d e code code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long t, n, tot, c[100010], le[100010];
long long f[210][210][210];
long long dfs(long long l, long long r, long long k)
{
if(f[l][r][k])
return f[l][r][k];
if(l==r)
return (le[r]+k)*(le[r]+k);
f[l][r][k]=dfs(l, r-1, 0)+(le[r]+k)*(le[r]+k);//直接删除l到r
for(long long i=l; i<r-1; i++)
if(c[i]==c[r])
f[l][r][k]=max(f[l][r][k], dfs(l, i, le[r]+k)+dfs(i+1, r-1, 0));
return f[l][r][k];
}
int main()
{
scanf("%lld", &t);
long long t1=0;
while(t--)
{
t1++;
scanf("%lld", &n);
long long last=0;
for(long long i=1; i<=n; i++)
{
long long x;
scanf("%lld", &x);
if(last==x)
le[tot]++;
else
c[++tot]=x, le[tot]=1;
last=x;
}
printf("Case %lld: %lld\n", t1, dfs(1, tot, 0));
memset(le, 0, sizeof(le));
memset(c, 0, sizeof(c));
memset(f, 0, sizeof(f));
tot=0;
}
}