这题在poj上做过,之前的博客已经有详细解释了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define ss(x) scanf("%d",&x)
const int maxn=200+10;
struct blocks{
int amount,color;
};
int n;
int a[maxn];
vector<blocks> v;
int f[maxn][maxn][maxn];
int dp(int l,int r,int ex_len)
{
if(f[l][r][ex_len]>=0) return f[l][r][ex_len];
int ans=(v[r].amount+ex_len)*(v[r].amount+ex_len);
if(l==r) return ans;
ans+=dp(l,r-1,0);
rep(i,l,r-1){
if(v[i].color!=v[r].color) continue;
ans=max(ans,dp(l,i,v[r].amount+ex_len)+dp(i+1,r-1,0));
}
return f[l][r][ex_len]=ans;
}
int main()
{
int kase=0;
int t;
ss(t);
while(t--)
{
v.clear();
ss(n);
rep(i,1,n) ss(a[i]);
rep(i,1,n) {if(a[i]!=a[i-1]) {v.push_back((blocks){1,a[i]});}else v[v.size()-1].amount++;}
memset(f,-1,sizeof(f));
printf("Case %d: %d\n",++kase,dp(0,(int)v.size()-1,0));
}
return 0;
}