http://poj.org/problem?id=1141
Description
Input
Output
Sample Input
([(]
Sample Output
()[()]
/** poj1141区间dp 给定一定长度的括号,求至少添加几个能是给定的括号匹配。 dp[i][j] 表示区间i~j之间至少要添加多少括号,从区间的长度由小变大依次遍历,a[i]==a[j],dp[i][j]=dp[i+1][j-1] 状态转移方程dp[i][j]=max(dp[i][k],dp[k][j]),k:i~j-1;每次更新都记录下更新的位置mark[i][j]=k, 最后递归输出即可。 */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> using namespace std; int dp[120][120]; int mark[120][120]; char a[120]; void print(int x,int y) { if(x>y) return; if(x==y) { if(a[x]=='('||a[x]==')') printf("()"); else printf("[]"); } else if(mark[x][y]==-1) { printf("%c",a[x]); print(x+1,y-1); printf("%c",a[y]); } else { print(x,mark[x][y]); print(mark[x][y]+1,y); } } int main() { scanf("%s",a); int n=strlen(a); memset(dp,0,sizeof(dp)); for(int i=0; i<n; i++) dp[i][i]=1; for(int l=1; l<n; l++) { for(int i=0; i<n-l; i++) { int j=i+l; dp[i][j]=111111111; if((a[i]=='('&&a[j]==')')||(a[i]=='['&&a[j]==']')) { dp[i][j]=dp[i+1][j-1]; mark[i][j]=-1; } for(int k=i; k<j; k++) { if(dp[i][j]>dp[i][k]+dp[k+1][j]) { dp[i][j]=dp[i][k]+dp[k+1][j]; mark[i][j]=k; } } } } print(0,n-1); puts(""); return 0; }