考虑dp[ l ][ r ]表示消除l到r的最大收益,但是这种表示无法表示中间不连续删除的情况,所以加上一维,表示 r 与 后面k个数字共同删除的最大收益
int a[222],cnt[222];
int dp[222][222][222];
//消除i到j及j后面k个与j颜色相同的块的最大收益
int dfs(int l,int r,int k)
{
if(l>r) return 0;
if(l==r) return dp[l][r][k]=(cnt[l]+k)*(cnt[l]+k);
if(dp[l][r][k]) return dp[l][r][k];
//第一种方案,最后一个位置和后面的k个一起消除,中间不留空
dp[l][r][k]=dfs(l,r-1,0)+(cnt[r]+k)*(cnt[r]+k);
//第二种方案,最后一个位置和前面某位置一起消除,中间空出一段
for(int i=l;i<r;++i)
{
if(a[i]!=a[r]) continue;
dp[l][r][k]=max(dp[l][r][k],dfs(l,i,cnt[r]+k)+dfs(i+1,r-1,0));
}
return dp[l][r][k];
}
int solve()
{
int n;cin>>n;
int pre=-1,pos=0;
memset(cnt,0,sizeof(cnt));
memset(dp,0,sizeof(dp));
rpp(i,n)
{
int x;cin>>x;
if(x!=pre) ++pos;
a[pos]=x;
++cnt[pos];
pre=x;
}
n=pos;
return dfs(1,n,0);
}