不明白为啥倒着刷表,顺着应该也行啊。
打印要用递归的思想,正是我的痛点啊。
注意输入串可能是空串,不能用scanf。。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn=1005; 8 9 int n; 10 int dp[maxn][maxn]; 11 char s[maxn]; 12 13 bool match(char a,char b){ 14 if(a=='('&&b==')') return true; 15 if(a=='['&&b==']') return true; 16 return false; 17 } 18 19 void solve(){ 20 for(int i=0;i<n;i++) { dp[i+1][i]=0; dp[i][i]=1; } //初始化 21 for(int i=n-2;i>=0;i--){ 22 for(int j=i+1;j<n;j++){ 23 dp[i][j]=n; 24 if(match(s[i],s[j])) dp[i][j]=min(dp[i][j],dp[i+1][j-1]); 25 for(int k=i;k<j;k++) dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); 26 } 27 } 28 } 29 30 void print(int i,int j){ 31 if(i>j) return ; 32 if(i==j){ 33 if(s[i]=='('||s[i]==')') printf("()"); 34 else printf("[]"); 35 return ; 36 } 37 int ans=dp[i][j]; 38 if(match(s[i],s[j])&&ans==dp[i+1][j-1]){ 39 printf("%c",s[i]); 40 print(i+1,j-1); 41 printf("%c",s[j]); 42 return ; 43 } 44 for(int k=i;k<j;k++){ 45 if(ans==dp[i][k]+dp[k+1][j]){ 46 print(i,k); 47 print(k+1,j); 48 return ; 49 } 50 } 51 } 52 53 int main() 54 { int kase; 55 cin>>kase; 56 getchar(); 57 while(kase--){ 58 gets(s); 59 gets(s); 60 n=strlen(s); 61 62 solve(); 63 print(0,n-1); 64 printf(" "); 65 if(kase) cout<<endl; 66 } 67 return 0; 68 }