UVa 10559 Blocks - 动态规划
Posted yyf0309
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 10559 Blocks - 动态规划相关的知识,希望对你有一定的参考价值。
标算的状态设计感觉比较神仙。
设$f_{l, r, k}$表示考虑到第$l$个方块到第$r$个方块,在第$r$个方块后面有$k$个和第$r$个方块的颜色一样的方块,将这些方块都消去能够得到的最大的分数。
首先不难发现每次消除一定消除的是当前一个极大颜色相同的连续段。
转移的时候考虑$r$所在原序列的一个极大颜色相同的连续段。显然有两种决策:
- 把它和后面的$k$的方块一起消掉。
- 把它作为$[l, r]$某个子区间$[l, r‘]$的右边和$r‘$颜色相同的方块,然后将$r‘$的后一个方块到$r$所在原序列的一个极大颜色相同的连续段的第一个方块的前一个方块之间的方块(包含端点)先消去(这样使得$r‘$和$r$所在的那个连续段连接在一起)。
时间复杂度$O(n^4)$。([一脸懵逼.gif])
Code
1 /** 2 * UVa 3 * Problem#10559 4 * Accepted 5 * Time: 670ms 6 */ 7 #include <iostream> 8 #include <cstdlib> 9 #include <cstring> 10 #include <cstdio> 11 using namespace std; 12 typedef bool boolean; 13 14 const int N = 205; 15 16 int n; 17 int a[N], f[N][N][N]; 18 19 inline void init() { 20 scanf("%d", &n); 21 for (int i = 1; i <= n; i++) 22 scanf("%d", a + i); 23 } 24 25 int dp(int l, int r, int append) { 26 if (l > r) 27 return 0; 28 int& rt = f[l][r][append]; 29 if (~rt) 30 return rt; 31 int cont = 1, k = r; 32 while (k > l && a[k - 1] == a[r]) 33 k--, cont++; 34 rt = dp(l, k - 1, 0) + (cont + append) * (cont + append); 35 for (int i = l; i < k; i++) 36 if ((a[i + 1] != a[i]) && a[i] == a[k]) 37 rt = max(rt, dp(l, i, append + cont) + dp(i + 1, k - 1, 0)); 38 return rt; 39 } 40 41 inline void solve() { 42 static int Kase = 0; 43 memset(f, -1, sizeof(f)); 44 printf("Case %d: %d ", ++Kase, dp(1, n, 0)); 45 } 46 47 int T; 48 int main() { 49 scanf("%d", &T); 50 while (T--) { 51 init(); 52 solve(); 53 } 54 return 0; 55 }
以上是关于UVa 10559 Blocks - 动态规划的主要内容,如果未能解决你的问题,请参考以下文章