poj-1179 Polygon **
2012-03-25 21:00
375 查看
/* * 枚举第一次断开的边,然后DP, * * DP还是很简单的, 类似矩阵连乘 * 需要注意的是:由于负负得正,所以你不能只算最大值. * 也就是说要计算多边形上连续的一段所能达到的最小值和最大值. * * 难的是断开第k条边后如何给剩下的边重新编号 * * 这里建立了一个映射,如断开第k条边, * 则原来的第k+1条边编号为0,原来的第k-1条边编号为n-2. * * getNum(i, k)函数用于计算断开第k条边后新编号为i的边的原编号 * * * */ #include <cstdio> using namespace std; const int maxn = 50 + 4; const int inf = 10000000; int n, vertex[maxn]; char edge[maxn]; int dpmin[maxn][maxn], dpmax[maxn][maxn], initdp[maxn]; inline int cal(int edgeNum, int a, int b){ if(edge[edgeNum] == 't') return a + b; else return a * b; } inline int getNum(int i, int k){ if(i > n-k-2) return i-(n-k-1); else return i+k+1; } //断开第k条边 // void init(int k){ for(int i=0; i<n; i++) for(int j=0; j<n; j++){ dpmin[i][j] = inf; dpmax[i][j] = -inf; } int j; for(int i=0; i<n; i++){ j = getNum(i, k); //初始化 dpmax[i][i] = dpmin[i][i] = initdp[j]; //为了后边DP时计算方便,把顶点的信息记录在dp数组里 dpmax[(i+1)%n][i] = dpmin[(i+1)%n][i] = vertex[j]; } } inline int min(int a, int b, int c, int d, int e){ int ans = a; if(ans > b) ans = b; if(ans > c) ans = c; if(ans > d) ans = d; if(ans > e) ans = e; return ans; } inline int max(int a, int b, int c, int d, int e){ int ans = a; if(ans < b) ans = b; if(ans < c) ans = c; if(ans < d) ans = d; if(ans < e) ans = e; return ans; } int main(){ scanf("%d\n", &n); char tmp; int ii; for(int i=0; i<n; i++){ scanf("%c %d", &edge[i], &vertex[i]); if(i<n-1) scanf("%c", &tmp); } for(int i=0; i<n; i++){ ii = (i-1+n) % n; initdp[i] = cal(i, vertex[ii], vertex[i]); } int jj, ans=-inf, rec[maxn], top = 0; for(int k=0; k<n; k++){ init(k); for(int l=1; l<n-1; l++){ for(int i=0; i<n-1-l; i++){ for(int j=i; j<=i+l; j++){ jj = getNum(j, k); ii = (j-1+n)%n; dpmin[i][i+l]=min(dpmin[i][i+l], cal(jj, dpmin[i][ii], dpmin[j+1][i+l]), cal(jj, dpmax[i][ii], dpmin[j+1][i+l]), cal(jj, dpmin[i][ii], dpmax[j+1][i+l]), cal(jj, dpmax[i][ii], dpmax[j+1][i+l])); dpmax[i][i+l]=max(dpmax[i][i+l], cal(jj, dpmin[i][ii], dpmin[j+1][i+l]), cal(jj, dpmax[i][ii], dpmin[j+1][i+l]), cal(jj, dpmin[i][ii], dpmax[j+1][i+l]), cal(jj, dpmax[i][ii], dpmax[j+1][i+l])); } } } //记录答案 if(ans < dpmax[0][n-2]){ ans = dpmax[0][n-2]; top = 0; rec[top++] = k; } else if(ans == dpmax[0][n-2]) rec[top++] = k; } //answer printf("%d\n", ans); for(int i=0; i<top-1; i++) printf("%d ", rec[i]+1); printf("%d\n", rec[top-1]+1); return 0; }
相关文章推荐
- POJ 1179 Polygon 区间DP
- POJ 1179 Polygon(区间DP)
- POJ 1179 Polygon(区间DP) -补充
- DP_ poj 1179 Polygon
- POJ 1179 Polygon
- poj1179 Polygon
- POJ 1179 Polygon (DP)
- poj1179 Polygon
- POJ 1179 Polygon(动态规划:类似环形石子合并)
- 【POJ1179】Polygon (动态规划 DP)
- poj 1179 Polygon(DP)
- POJ 1179 Polygon(环形区间DP)
- poj 1179 Polygon
- poj 1179 Polygon
- POJ 1179 Polygon(区间DP)
- POJ 1179 Polygon 矩阵链乘 记忆化搜索
- POJ 1179 Polygon
- POJ-1179 Polygon (动态规划)
- poj 1179 Polygon(化环为直+区间dp)
- POJ1179——Polygon