标签:
/* dp 如果是统计最少加多少个括号 就是区间dp 如果区间两头是匹配的 就可以用 i+1 j-1 更新 然而这题要输出方案 就类似记路径 记背包选哪几个一样 维护一个bj表示 i到j的最优解是由 分成哪两份转移来的 如果无法分 就是-1 最后递归搞输出方案 递归终点就是需要改变的点 */ #include<iostream> #include<cstdio> #include<cstring> using namespace std; int l,f[110][110],bj[110][110],a[110]; char s[110]; void Dfs(int x,int y) { if(x>y)return; if(x==y)a[x]=1; if(bj[x][y]==-1)Dfs(x+1,y-1); else if(bj[x][y]>0) { Dfs(x,bj[x][y]); Dfs(bj[x][y]+1,y); } } int main() { scanf("%s",s+1); l=strlen(s+1); if(l==0)//特判特判 { printf("\n"); return 0; } for(int i=1;i<=l;i++) f[i][i]=1; for(int i=l-1;i>=1;i--) for(int j=i+1;j<=l;j++) { f[i][j]=99999999; if((s[i]==‘(‘&&s[j]==‘)‘)||(s[i]==‘[‘&&s[j]==‘]‘)) if(f[i][j]>f[i+1][j-1]) { f[i][j]=f[i+1][j-1]; bj[i][j]=-1; } for(int k=i;k<j;k++) if(f[i][k]+f[k+1][j]<f[i][j]) { f[i][j]=f[i][k]+f[k+1][j]; bj[i][j]=k; } } Dfs(1,l); for(int i=1;i<=l;i++) if(a[i]) { if(s[i]==‘(‘||s[i]==‘)‘)printf("()"); else printf("[]"); } else printf("%c",s[i]); return 0; }
标签:
原文地址:http://www.cnblogs.com/yanlifneg/p/5495744.html