【YBTOJ】【UVA10559】方塊消除 Blocks
阿新 • • 發佈:2021-07-08
【YBTOJ】【UVA10559】方塊消除 Blocks
連結:
題目大意:
有 \(n\) 個帶有顏色的方塊,沒消除一段長度為x的連續的相同顏色的方塊可以得到 \(x^2\) 的分數,讓你用一種最優的順序消除所有方塊使得得分最多。
正文:
考慮區間 DP。若用一般狀態 \(f_{l,r}\) 很難算、不方便,就再設一維:\(f_{l,r,k}\) 表示 \([l,r]\) 後,還有 \(k\) 個與 \(r\) 顏色相同的塊的最大得分。
就有兩種轉移的方法:
\[\left.\begin{matrix} f_{i,j-1,0} + (k+1)^2 &\rightarrow &f_{i,j,k} \\ f_{i,p,k+1} + f_{p+1,j-1,0} &\rightarrow &f_{i,j,k} \end{matrix}\right\}\]其中 \(p\)
程式碼:
const int N = 210; inline ll Read() { ll x = 0, f = 1; char c = getchar(); while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') f = -f, c = getchar(); while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar(); return x * f; } int t, n; int a[N], nxt[N], head[N]; ll f[N][N][N]; ll dfs(int i, int j, int k) { if (i > j) return 0; if (f[i][j][k]) return f[i][j][k]; ll ans = dfs(i, j - 1, 0) + (k + 1) * (k + 1); for (int p = nxt[j]; p >= i; p = nxt[p]) ans = max(ans, dfs(i, p, k + 1) + dfs(p + 1, j - 1, 0)); return f[i][j][k] = ans; } int main() { t = Read(); for (int T = 1; T <= t; T++) { memset (f, 0, sizeof f); memset (nxt, 0, sizeof nxt); memset (head, 0, sizeof head); n = Read(); for (int i = 1; i <= n; i++) a[i] = Read(), nxt[i] = head[a[i]], head[a[i]] = i; printf ("Case %d: %d\n", T, dfs(1, n, 0)); } return 0; }