这道题让我新认识到的是,做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;
}