POJ 1141 Brackets Sequence (DP+路径处理)
来源:互联网 发布:淘宝首页客服模块 编辑:程序博客网 时间:2024/06/04 01:03
/*** 挺不错的DP题,黑书dp专题第一例。* 输出搞了近一个小时的输出,结果发现不是输出的问题,* 是在处理pos和dp数组的时候更新dp用的是dp[.]=min(dp[.],dp[..])的形式。* 忽略了pos[i][j]的更新应该在满足dp[..] < dp[.]的时候才更新的* 所以建议还是少用min去更新,避免遗漏还是if(dp[.]>dp[..]){...}的形式更新* 至于如何dp,黑书上讲的也挺详细的,dp[i][j]表示下标从i到j的子串变成合法形式* 所添加的最少括号数。 这样在递推求dp的过程就是区间长度(i-j+1)从1一直到len-1去更新* 当前最优子结构dp[i][j]* 状态转移方程就是: dp[i][j] = min(dp[i][j], dp[i][z]+dp[z+1][j]) z在i到j-1范围枚举* 其余要注意的是,初始化的时候dp[i][i] = 1; dp[i][i+1] = 0;* 为什么dp[i][i+1] 要初始化为0?* 因为: 当str[i]和str[j]能正常配对且j=i+1的时候, dp[i][j] = dp[i+1][j-1];* 这个时候因为dp[i][j]已经是合法的,所以值应该是0,所以dp[i][i+1]都要初始化为0*/#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <string>#include <queue>#include <map>#include <vector>#include <algorithm>#define DEBUG 0#define INF 0x1fffffff#define MAXN 105typedef long long LL;using namespace std;int dp[MAXN][MAXN], pos[MAXN][MAXN];int len;char str[MAXN];void print(int l, int r){ if(l > r) return ; if(l == r) { if(str[l] == '(' || str[l] == ')') printf("()"); else printf("[]"); return ; } if(pos[l][r] == -1) { printf("%c", str[l]); print(l+1, r-1); printf("%c", str[r]); return ; } print(l, pos[l][r]); print(pos[l][r]+1, r);}void dpf(){ for(int i = 0; i <= len; i ++) { dp[i][i] = 1; dp[i][i+1] = 0; } for(int k = 1; k < len; k ++) { for(int i = 1; i <= len - k; i ++) { int j = i + k; dp[i][j] = INF; pos[i][j] = -1; if(str[i] == '(' && str[j] == ')' || str[i] == '[' && str[j] == ']' ) { dp[i][j] = dp[i+1][j-1]; } for(int z = i; z < j; z ++) { if(dp[i][j] > dp[i][z] + dp[z+1][j]) { dp[i][j] = dp[i][z] + dp[z+1][j]; pos[i][j] = z; } } } }}int main(){ scanf("%s", str+1); len = strlen(str+1); dpf(); print(1, len); puts(""); return 0;}