这道题让我新认识到的是,做dp题,不一定非得找到具体的某一个最优子结构,可以美剧所有可能子结构的最优解,通过比较得到结果。向此题,只要找到和子结构之间的关系,然后选取最大的,之前一直死去想最有子结构,后来看了黑书。发现lrj所说,只是去找子问题中的最优解。还有就是数据中有空字符串,要注意
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=110; const int inf=1<<30; char s[maxn]; int in[maxn][maxn],f[maxn][maxn]; void print(int i,int j) { char c1=s[i],c2=s[j],c3,c4; c3=c1=='('?')':']';c4=c2==')'?'(':'['; if(i>j) return;//容易疏忽的一步 else if(i==j) { if(s[i]=='('||s[i]==')') cout<<"()"; else cout<<"[]"; } else if(in[i][j]==-3) { cout<<c1; print(i+1,j-1); cout<<c2; } else if(in[i][j]==-2) { cout<<c1; print(i+1,j); cout<<c3; } else if(in[i][j]==-1) { cout<<c4; print(i,j-1); cout<<c2; } else { print(i,in[i][j]); print(in[i][j]+1,j); } } int main() { int n; cin>>n; while(n--) { int i,j,k,t; gets(s); int len=strlen(s); if(len==0) { cout<<endl; continue; } for(i=0;i<len;i++) { f[i][i]=1; in[i][i]=-4; } for(k=2;k<=len;k++) { for(i=0;i<=len-k;i++) { j=i+k-1; f[i][j]=inf; if(s[i]=='('&&s[j]==')'||s[i]=='['&&s[j]==']') { f[i][j]=f[i+1][j-1]; in[i][j]=-3; } if(s[i]=='('||s[i]=='[') { if(f[i][j]>f[i+1][j]+1) { f[i][j]=f[i+1][j]+1; in[i][j]=-2; } } if(s[j]==')'||s[j]==']') { if(f[i][j]>f[i][j-1]+1) { f[i][j]=f[i][j-1]+1; in[i][j]=-1; } } for(t=i;t<j;t++) { if((f[i][t]+f[t+1][j])<f[i][j]) { f[i][j]=f[i][t]+f[t+1][j]; in[i][j]=t; } } } } print(0,len-1); cout<<endl; } return 0; }