动态规划,递归
难
参考:https://blog.csdn.net/PKU_ZZY/article/details/51442591
//动态规划,递归
#include <iostream>
#include <cstring>
using namespace std;
const int N = 201;
int t, n, m;
int color[N];
int num[N], c[N];
int ans[N][N][N];
//r位右边,与r同色的还有len个情况下,[l,r]区间上的最大分数
int func(int l, int r, int len) {
int tmp,k;
if (l == r)
return ans[l][r][len] = (num[r] + len) * (num[r] + len);
if (ans[l][r][len])//递归出口
return ans[l][r][len];
tmp = func(l, r - 1, 0) + (len + num[r]) * (len + num[r]);//r位和右边的直接合并,消
for (k = l; k < r; k++) {
if (c[k] == c[r]) {//左边的第k位和r位同色
//进一步合并再消
if (func(l, k, num[r] + len) + func(k + 1, r - 1, 0) > tmp)
tmp = func(l, k, num[r] + len) + func(k + 1, r - 1, 0);
}
}
return ans[l][r][len] = tmp;
}
int main() {
int i, j;
cin >> t;
color[0] = 0;
for (i = 1; i <= t; i++) {
memset(ans, 0, sizeof(ans));
cin >> n;
m = 0;
for (j = 1; j <= n; j++) {
cin >> color[j];
if (color[j] == color[j - 1])
num[m]++;
else {//预处理,令相邻同色块合并成一个大块
m++;
c[m] = color[j];
num[m] = 1;
}
}
printf("Case %d: %d\n", i, func(1, m, 0));
}
return 0;
}