1. 程式人生 > >洛谷 P4342 / poj 1179 Polygon

洛谷 P4342 / poj 1179 Polygon

n) for 這一 最小 col tween string 2.0 lse

看到這種拆邊成鏈的問題,第一反應就是區間dp.

這一題的難點在狀態轉移上。單純儲存最大值不能滿足dp中最優子結構的性質。

從轉移角度入手,發現最大值的來源可能是兩個最大值相加,相乘,兩個最小值的相乘(不過把這個最小值相乘的去掉好像對答案沒有什麽影響);

最小值的來源可能是兩個最小值相加,相乘,或者最大值和最小值相乘(正負得負)。

根據這個想法,不難想出用 f[ i ][ j ][ 0 / 1 ]儲存從 i 到 j 的最大值與最小值.

最後,把鏈拆開復制一倍,跑一下區間dp就可以在O(N3)的時間內求出答案了!

 1 #include <cstdio>
 2 #include <cstring>
 3
#include <algorithm> 4 #include <iostream> 5 using namespace std; 6 const int MAXN = 55; 7 const int INF = 0x3f3f3f3f; 8 9 int N; 10 int f[MAXN * 2][MAXN * 2][2];//1->max, 0->min 11 int W[MAXN * 2], opt[MAXN * 2]; 12 //opt : 1.opt[i]->opt between i and i + 1; 13 // 2.0->‘+‘, 1->‘*‘;
14 15 16 int main() 17 { 18 //freopen("p4342.in", "r", stdin); 19 scanf("%d", &N); 20 21 char ch; 22 for(int i = 1; i <= N * 2; i++) 23 { 24 if(i % 2 == 1) 25 { 26 scanf(" %c", &ch); 27 opt[i / 2] = ch == x; 28 } 29 else
30 scanf(" %d", &W[i / 2]); 31 } 32 33 for(int i = N + 1; i <= 2 * (N + 1); i++) 34 { 35 W[i] = W[i - N]; 36 opt[i - 1] = opt[i - N - 1]; 37 } 38 39 //for(int i = 1; i <= 2 * N; i++) 40 // cout<<W[i]<<" "; 41 42 for(int i = 1; i <= 2 * N; i++) 43 for(int j = 1; j <= 2 * N; j++) 44 f[i][j][0] = INF, f[i][j][1] = -INF; 45 46 for(int i = 1; i <= 2 * N; i++) 47 f[i][i][1] = f[i][i][0] = W[i]; 48 49 for(int len = 2; len <= N; len++) 50 for(int l = 1; l <= (2 * N - len + 1); l++) 51 { 52 int r = l + len - 1; 53 for(int k = l; k < r; k++) 54 { 55 if(opt[k] == 1) 56 { 57 f[l][r][0] = min(f[l][k][0] * f[k + 1][r][1], f[l][r][0]); 58 f[l][r][0] = min(f[l][k][1] * f[k + 1][r][0], f[l][r][0]); 59 f[l][r][0] = min(f[l][k][0] * f[k + 1][r][0], f[l][r][0]); 60 f[l][r][0] = min(f[l][k][1] * f[k + 1][r][1], f[l][r][0]); 61 62 f[l][r][1] = max(f[l][k][0] * f[k + 1][r][0], f[l][r][1]); 63 f[l][r][1] = max(f[l][k][1] * f[k + 1][r][1], f[l][r][1]); 64 } 65 else 66 { 67 f[l][r][0] = min(f[l][k][0] + f[k + 1][r][0], f[l][r][0]); 68 f[l][r][1] = max(f[l][k][1] + f[k + 1][r][1], f[l][r][1]); 69 } 70 } 71 } 72 73 74 int ans = -INF; 75 for(int i = 1; i <= N; i++) 76 ans = max(ans, f[i][i + N - 1][1]); 77 cout<<ans<<endl; 78 for(int i = 1; i <= N; i++) 79 if(f[i][i + N - 1][1] == ans) 80 cout<<i<<" "; 81 return 0; 82 }

洛谷 P4342 / poj 1179 Polygon