- 题意:消除相同相邻方块获得消除长度的平方,求消完后最大获得值
- 思路:容易想到贪心,可是长度的不确定性,以及平方的难以处理。还有数据范围告诉我们用高维dp
首先容易想到状态\([l,r]\)表示消完该范围的最大获得值。但是显然无法处理消后合并的情况。合并怎么搞?会发现我们提前用到合并操作的时候是两端相同才有意义,不然我们采用从后往前消的策略。然后便会想到存储一维右边相等颜色块的个数。
然后决策:直接消完右端或者取中间一点\(p\)满足\(a[p]==a[r]\)且\(a[p+1]!=a[r]\)然后我们删\([p+1,q-1]\)就非常的方便可爱。
- 代码:
//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;
}