POJ 1179 Polygon(环形DP 矩阵连乘)
2014-03-23 10:40
381 查看
题意:给出一个环 环上的每个点有一个值 点和点之间用一条边相连,边上有一个运算符,要求删除一条边,然后对剩下的线两两顶点合并运算.求通过运算能得到的最大值.并求出删除某条边后能经过运算得到这个最大值的这些边.
由于N<=50,所以可以枚举每一个断开点,对断开后形成的线做类似矩阵连乘的DP,这样的复杂度为O(N^4)还是可以接受的.
要注意的是最大值可能有最小值相乘得到(负数),所以也要记录最小值.
设dp1[i][j]为从i到j的最大运算结果,dp2为最小值
那么
dp1[i][j] = max(dp1[i][j], dp1[i][k] + dp1[k + 1][j] | i<=k<j)
dp1[i][j] = max(dp1[i][j], dp1[i][k] * dp1[k + 1][j], dp1[i][k] * dp2[k + 1][j], dp2[i][k] * dp1[k + 1][j], dp2[i][k] * dp2[k + 1][j] | i <= k < j)
dp2的方程和上面差不多,只不过max变成了min
由于N<=50,所以可以枚举每一个断开点,对断开后形成的线做类似矩阵连乘的DP,这样的复杂度为O(N^4)还是可以接受的.
要注意的是最大值可能有最小值相乘得到(负数),所以也要记录最小值.
设dp1[i][j]为从i到j的最大运算结果,dp2为最小值
那么
dp1[i][j] = max(dp1[i][j], dp1[i][k] + dp1[k + 1][j] | i<=k<j)
dp1[i][j] = max(dp1[i][j], dp1[i][k] * dp1[k + 1][j], dp1[i][k] * dp2[k + 1][j], dp2[i][k] * dp1[k + 1][j], dp2[i][k] * dp2[k + 1][j] | i <= k < j)
dp2的方程和上面差不多,只不过max变成了min
#include <cstdio> #include <memory.h> #include <climits> #include <algorithm> using namespace std; const int MAX = 122; char edg[MAX][2]; int vet[MAX]; int dp1[MAX / 2][MAX / 2], dp2[MAX / 2][MAX / 2]; int final[MAX]; int N; int main(int argc, char const *argv[]){ int ans_max = INT_MIN, N; scanf("%d", &N); for(int i = 0; i < N; ++i){ scanf("%s %d", edg[i], &vet[i]); edg[i + N][0] = edg[i][0]; vet[i + N] = vet[i]; } //enumerate every cutting point for(int k = 0; k < N; ++k){ //base cases for(int i = 0; i < N; ++i){ dp1[i][i] = vet[k + i]; dp2[i][i] = vet[k + i]; } //do DP for every line after cutting for(int i = 1; i < N; ++i){ for(int j = 0; j + i< N; ++j){ int maxv = INT_MIN, minv = INT_MAX; for(int p = j; p < j + i; ++p){ if(edg[p + k + 1][0] == 't'){ maxv = max(maxv, dp1[j][p] + dp1[p + 1][j + i]); minv = min(minv, dp2[j][p] + dp2[p + 1][j + i]); }else{ //minimum times minimum might result in maximum maxv = max(maxv, dp1[j][p] * dp1[p + 1][j + i]); maxv = max(maxv, dp1[j][p] * dp2[p + 1][j + i]); maxv = max(maxv, dp2[j][p] * dp1[p + 1][j + i]); maxv = max(maxv, dp2[j][p] * dp2[p + 1][j + i]); //vice versa minv = min(minv, dp1[j][p] * dp1[p + 1][j + i]); minv = min(minv, dp1[j][p] * dp2[p + 1][j + i]); minv = min(minv, dp2[j][p] * dp1[p + 1][j + i]); minv = min(minv, dp2[j][p] * dp2[p + 1][j + i]); } } dp1[j][j + i] = maxv; dp2[j][j + i] = minv; } } ans_max = max(ans_max, dp1[0][N - 1]); final[k] = dp1[0][N - 1]; } printf("%d\n", ans_max); for(int i = 0; i < N; ++i){ if(final[i] == ans_max){ printf("%d ", i + 1); } } printf("\n"); return 0; }
相关文章推荐
- poj 1179 循环dp 类似矩阵连乘
- poj 1179 Polygon(动态规划:矩阵连乘加强)
- POJ 1179 Polygon(环形区间DP)
- POJ 1179 Polygon 区间DP
- DP_ poj 1179 Polygon
- 【POJ1179】Polygon (动态规划 DP)
- POJ 1179 Polygon(动态规划:类似环形石子合并)
- POJ 1179 Polygon(区间DP) -补充
- POJ 1179 Polygon (DP)
- poj 1179 Polygon(DP)
- POJ 1179 Polygon 记忆化dfs vs dp
- POJ 1179 Polygon(DP)
- poj 1179 Polygon(化环为直+区间dp)
- POJ-1651 Multiplication Puzzle 矩阵连乘问题(区间dp)
- POJ1179 Polygon [DP 矩阵链乘]
- 经典问题五.【乘号两边有正负 区间dp】Polygon poj 1179
- POJ 1179 Polygon (DP)
- POJ 1179 Polygon(区间DP)
- POJ 1179 Polygon(区间DP)
- POJ 1179 Polygon(区间DP)