• 题意:消除相同相邻方块获得消除长度的平方,求消完后最大获得值
  • 思路:容易想到贪心,可是长度的不确定性,以及平方的难以处理。还有数据范围告诉我们用高维dp
    首先容易想到状态[l,r]表示消完该范围的最大获得值。但是显然无法处理消后合并的情况。合并怎么搞?会发现我们提前用到合并操作的时候是两端相同才有意义,不然我们采用从后往前消的策略。然后便会想到存储一维右边相等颜色块的个数。
    然后决策:直接消完右端或者取中间一点p满足a[p]==a[r]a[p+1]!=a[r]然后我们删[p+1,q1]就非常的方便可爱。
  • 代码:
//dp[l][r][k]=max{dp[l][q-1][0]+(r+k-q+1)^2,dp[l][p][r+k-q+1]+dp[p+1][q-1][0]}
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=205;
int dp[N][N][N],a[N];
int DP(int l,int r,int k) {
	if(dp[l][r][k]!=-1) return dp[l][r][k];
	if(l>r) return 0;
	int p,q=r,mx=0;
	while(q>1&&a[q-1]==a[r]) q--;
	mx=max(mx,DP(l,q-1,0)+(r+k-q+1)*(r+k-q+1));
	for(p=l;p<q;p++) {
		if(a[p]==a[r]&&a[p+1]!=a[r]) {
			mx=max(mx,DP(l,p,r+k-q+1)+DP(p+1,q-1,0));
		}
	}
	return dp[l][r][k]=mx;
}
int main() {
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) {
		scanf("%d",&a[i]);
	}
	memset(dp,-1,sizeof(dp));
	printf("%d",DP(1,n,0));
	return 0;
}