消木块

简介: 消木块

你们中的一些人可能玩过一个叫做消木块的游戏。

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));
    }
}
目录
相关文章
|
6月前
记录一次button闪烁问题
记录一次button闪烁问题
26 0
|
12天前
|
JavaScript 开发者
【掰开揉碎】深入了解 @tap 和 @click
【掰开揉碎】深入了解 @tap 和 @click
|
4月前
失焦事件和点击事件
失焦事件和点击事件
20 1
|
10月前
|
JavaScript 前端开发
常用的click事件居然这么多门道,赶紧卷
你真的了解 onclick 点击事件吗? onclick 是异步的还是同步的?事件的触发顺序你了解过吗?现在我就带你一起来了解一下 onclick 事件前后左右的一些事情。
105 0
|
前端开发
click事件无法触发、div存取数值
.项目中遇到的问题,button的click无法触发,点击按钮,断点都没有走到click里面。那就是click方法没有被触发,那就需要绑定事件。
181 0
|
JavaScript 前端开发 数据安全/隐私保护
使用 button 的 5 个理由
使用 button 的 5 个理由
使用 button 的 5 个理由

热门文章

最新文章