poj 1390 Blocks 区间DP
Posted rorshach
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 1390 Blocks 区间DP相关的知识,希望对你有一定的参考价值。
Description:
给你一堆方块,颜色相同可以消去,每次消去的价值为消去方块的个数的平方。单个方块可以消去。问你最后收获的最大价值为多少
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 const int N = 220; 6 int dp[N][N][N], g[N][N], col[N]; 7 //dp[i][j][k]表示i-j这一段消得只剩k个且k个块都相同时收获的最大价值,g[i][j]表示i-j能收获的最大价值 8 int n, m; 9 int main(){ 10 int T, kase = 0; 11 scanf("%d", &T); 12 while(T--){ 13 scanf("%d", &n); 14 for(int i = 1; i <= n; i++) scanf("%d", &col[i]); 15 memset(dp, -63, sizeof(dp)); //达不到的状态为负无穷大 16 memset(g, 0, sizeof(g)); 17 for(int i = 1; i <= n; i++) 18 dp[i][i][1] = 0, dp[i][i][0] = 0, g[i][i] = 1; 19 for(int l = 2; l <= n; l++) 20 for(int i = 1, j; i + l - 1 <= n; i++){ //枚举区间 21 j = i + l - 1; 22 if(col[i] == col[j]){ //如果区间首尾相同 说明可能通过消去区间内的方块更新dp数组 23 for(int k = 1; k <= l; k++){ //枚举可能的相同剩余方块数 24 for(int t = i; t < j; t++) //枚举区间的每个方块 25 if(col[i] == col[t]) //如果发现有方块与区间首方块相同 26 //那么i到t的方块可以消掉t+1-j的方块后 达到dp[i][t][k-1]的状态 27 //把两边的两边产生的价值累加之后更新dp数组 28 dp[i][j][k] = max(dp[i][j][k], dp[i][t][k - 1] + g[t + 1][j - 1]); 29 //那么区间g[i][j]的价值可以表现为状态dp[i][j][k]的价值和消掉剩下的k个方块的价值 30 g[i][j] = max(g[i][j], dp[i][j][k] + k * k); 31 } 32 } 33 for(int k = i; k < j; k++) //重新刷一波更新g数组 34 g[i][j] = max(g[i][j], g[i][k] + g[k + 1][j]); 35 } 36 printf("Case %d: %d ", ++kase, g[1][n]); 37 } 38 return 0; 39 }
以上是关于poj 1390 Blocks 区间DP的主要内容,如果未能解决你的问题,请参考以下文章