http://poj.org/problem?id=1141
括号序列问题
有几个注意点:
(1)不能用scanf("%s", str), 而要用gets(str),因为输入可能含有空格(空序列'' "符合要求);
(2)‘ l ’表示所考虑对象的长度, 从0到n-1枚举(故单独处理dp[i][i]);
(3)dp[i][j]表示‘ i ’到 ‘ j ’的最小长度,也可以换种意义,表示‘ i ’到‘ j ’的最小添加长度,此时所有dp[i][j]要做适当调整。
具体代码:
View Code
#include<stdio.h> #include<string.h> char str[120]; int n, dp[120][120], mark[120][120]; void solve() { int i, j, k, l; for(i=0;i<n;i++) dp[i][i]=1; for(l=1;l<n;l++) for(i=0;i<n-l;i++) { j=i+l; dp[i][j]=(1<<15); if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']') { dp[i][j]=dp[i+1][j-1]; mark[i][j]=-1; } for(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; } } } void out(int ps, int pt) { if(ps>pt) return ; else if(ps==pt) { if(str[ps]=='('||str[ps]==')') printf("()"); else printf("[]"); } else if(mark[ps][pt]==-1) { printf("%c", str[ps]); out(ps+1, pt-1); printf("%c", str[pt]); } else { out(ps, mark[ps][pt]); out(mark[ps][pt]+1, pt); } } int main() { int i; while(gets(str)!=NULL) { n=strlen(str); solve(); out(0, n-1); printf("\n"); } return 0; }
