1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- #include <algorithm>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- const int N = 200;
- int dp[N][N][N];
- // dp[i][j][k] means the highest score for clearing blocks i ~ j.
- struct Segment {
- int color;
- int len;
- };
- Segment seg[N];
- // Clear the blocks from i to j, with extra len of block having the same color as seg[j].
- int clear(int i, int j, int len) {
- if (dp[i][j][len] != -1) return dp[i][j][len];
- int score = (seg[j].len + len) * (seg[j].len + len);
- if (i == j) return score;
- score += clear(i, j - 1, 0);
- for (int k = i; k + 1 <= j - 1; k++) {
- if (seg[k].color != seg[j].color) continue;
- score = max(score, clear(k + 1, j - 1, 0) + clear(i, k, seg[j].len + len));
- }
- dp[i][j][len] = score;
- return score;
- }
- int main() {
- int T, n;
- scanf("%d", &T);
- for (int t = 1; t <= T; t++) {
- scanf("%d", &n);
- int cnt = -1, pre = -1;
- for (int i = 0; i < n; i++) {
- int color;
- scanf("%d", &color);
- if (color != pre) {
- seg[++cnt].color = color;
- seg[cnt].len = 1;
- pre = color;
- } else {
- seg[cnt].len++;
- }
- }
- memset(dp, 0xFF, sizeof(dp));
- printf("Case %d: %d\n", t, clear(0, cnt, 0));
- }
- return 0;
- }
|