你们中的一些人可能玩过一个叫做消木块的游戏。
n 个木块排成一列,每个木块都有一个颜色。
例如下图中木块的颜色分别为:金,银,银,银,银,铜,铜,铜,金。
1390_1.jpg
每次,你都可以点击一个木块,这样被点击的木块以及和它相邻并且同色的木块就会消除。
如果一次性消除了 k 个木块,那么就会得到 k×k 分。
例如下图所示,点击银色木块,四个木块被消去,得到 16 分。
1390_2.jpg
给定你一个游戏初始状态,请你求出最高得分是多少。
输入格式
第一行包含整数 t,表示共有 t 组测试数据。
每组数据第一行包含整数 n,表示共有 n 个木块。
第二行包含 n 个整数,表示 n 个木块的颜色。
代表木块颜色的整数范围是 1∼n。
输出格式
每组数据输出一个结果,每个结果占一行。
输出格式为 Case x: y,其中 x 为数据组别编号,从 1 开始,y 为结果。
数据范围
1≤n≤200
输入样例:
2
9
1 2 2 2 2 3 3 3 1
1
1
输出样例:
Case 1: 29
Case 2: 1
加状态的区间dp
图解
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <bitset>
#include <assert.h>
using namespace std;
typedef long long llong;
typedef set<int>::iterator ssii;
#define Cmp(a, b) memcmp(a, b, sizeof(b))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define Set(a, v) memset(a, v, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define _forS(i, l, r) for(set<int>::iterator i = (l); i != (r); i++)
#define _rep(i, l, r) for(int i = (l); i <= (r); i++)
#define _for(i, l, r) for(int i = (l); i < (r); i++)
#define _forDown(i, l, r) for(int i = (l); i >= r; i--)
#define debug_(ch, i) printf(#ch"[%d]: %d\n", i, ch[i])
#define debug_m(mp, p) printf(#mp"[%d]: %d\n", p->first, p->second)
#define debugS(str) cout << "dbg: " << str << endl;
#define debugArr(arr, x, y) _for(i, 0, x) { _for(j, 0, y) printf("%c", arr[i][j]); printf("\n"); }
#define _forPlus(i, l, d, r) for(int i = (l); i + d < (r); i++)
#define lowbit(i) (i & (-i))
const int maxn = 200 + 10;
int f[maxn][maxn][maxn];
int A[maxn];
int N;
void init() {
Set(f, -1);
}
int dp(int i, int j, int k) {
if(i > j) return 0;
int& ans = f[i][j][k];
if(i == j) return ans = (1 + k) * (1 + k);
if(ans >= 0) return ans;
int p = j;
while (p >= i && A[p] == A[j]) p--;
p++;
ans = dp(i, p-1, 0) + (k + j-p+1) * (k + j-p+1);
_for(q, i, p) {
if(A[q] == A[j] && A[q+1] != A[q]) {
ans = max(ans, dp(i, q, k+j-p+1) + dp(q+1, p-1, 0));
}
}
return ans;
}
int main() {
freopen("input.txt", "r", stdin);
int T;
scanf("%d", &T);
_rep(kase, 1, T) {
printf("Case %d: ", kase);
scanf("%d", &N);
_rep(i, 1, N) scanf("%d", &A[i]);
init();
// then dp()
printf("%d\n", dp(1, N, 0));
}
}