「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的主要内容,如果未能解决你的问题,请参考以下文章