「UVA10559」Blocks

Posted zsbzsb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「UVA10559」Blocks相关的知识,希望对你有一定的参考价值。

传送门
Luogu

解题思路

考虑区间 ( ext{DP})
(f[i][j][k]) 表示 ([i,j]) 这段区间接上后面 (k) 个与 (j) 颜色相同的块得到的答案。
转移就是:
(f[i][j][k] = maxleft{f[i][j][0]+(k+1)^2 ight})
(f[i][j][k] = maxleft{f[i][p][k+1]+f[p+1][j-1][0] ight}(pin[i, j] ext{且}c_p=c_j))
第一个方程就是把后面那一坨一起消掉,再消掉前面。
第二个方程就是在中间找一个与 (j) 颜色相同的点 (p) ,把 ([p+1,j-1]) 这段先消掉,然后让剩下的两坨拼起来再消。
写成记搜很方便的说

细节注意事项

  • 咕咕咕

参考代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while (!isdigit(c)) f |= (c == '-'), c = getchar();
    while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
    s = f ? -s : s;
}

const int _ = 202;

int n, a[_], f[_][_][_], pre[_], las[_];

inline int dfs(int i, int j, int k) {
    if (i > j) return 0;
    if (f[i][j][k]) return f[i][j][k];
    f[i][j][k] = max(f[i][j][k], dfs(i, j - 1, 0) + (k + 1) * (k + 1));
    for (rg int p = pre[j]; p >= i; p = pre[p])
        f[i][j][k] = max(f[i][j][k], dfs(i, p, k + 1) + dfs(p + 1, j - 1, 0));
    return f[i][j][k];
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
#endif
    int T; read(T);
    for (rg int o = 1; o <= T; ++o) {
        memset(f, 0, sizeof f);
        memset(pre, 0, sizeof pre);
        memset(las, 0, sizeof las);
        read(n);
        for (rg int i = 1; i <= n; ++i) read(a[i]);
        for (rg int i = 1; i <= n; ++i) pre[i] = las[a[i]], las[a[i]] = i;
        printf("Case %d: %d
", o, dfs(1, n, 0));
    }
    return 0;
}

完结撒花 (qwq)

以上是关于「UVA10559」Blocks的主要内容,如果未能解决你的问题,请参考以下文章

UVA - 10559 Blocks

luogu UVA10559 ybtoj 区间DP课堂过关 例题3消除木块 & 方块消除 Blocks

UVa 10559 Blocks - 动态规划

Uva10559Blocks(区间DP)

UVa 10559 Blocks (DP)

UVA10559 Blocks(区间dp)