dp uva1626 括号序列
状态转移
d(i,j)表示子串S[i~j]至少需要加几个括号
递推写法 快
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 100+5; 5 char S[maxn]; 6 int n,d[maxn][maxn]; 7 8 bool match(char a, char b){ 9 return (a=='(' && b==')') || (a=='[' && b==']'); 10 } 11 12 void dp(){ 13 for(int i=0; i<n; i++){ 14 d[i+1][i] = 0; 15 d[i][i] = 1; 16 } 17 18 for(int i=n-2; i>=0; i--) 19 for(int j=i+1; j<n; j++){ 20 d[i][j] = n; 21 if(match(S[i],S[j])) d[i][j] = min(d[i][j],d[i+1][j-1]); 22 for(int k=i; k<j; k++){ 23 d[i][j] = min(d[i][j],d[i][k]+d[k+1][j]); 24 } 25 } 26 } 27 28 void print(int i,int j){ 29 if(i>j) return ; 30 if(i==j){ 31 if(S[i]=='(' || S[i]==')') printf("()"); 32 else printf("[]"); 33 return; 34 } 35 int ans = d[i][j]; 36 if(match(S[i],S[j]) && ans==d[i+1][j-1]) { 37 printf("%c",S[i]); print(i+1,j-1); printf("%c",S[j]); 38 return ; 39 } 40 41 for(int k=i; k<j; k++){ 42 if(ans == d[i][k]+d[k+1][j]){ 43 print(i,k); print(k+1,j); 44 return; 45 } 46 } 47 } 48 49 void readline(char* S){ 50 fgets(S,maxn,stdin); 51 } 52 53 int main(){ 54 int T; 55 readline(S); 56 sscanf(S,"%d",&T); 57 readline(S); 58 59 while(T--){ 60 readline(S); 61 n = strlen(S)-1; 62 memset(d,-1,sizeof(d)); 63 dp(); 64 print(0,n-1); 65 printf("\n"); 66 if(T) printf("\n"); 67 readline(S); 68 } 69 70 71 }
记忆化搜索 慢
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 100+5; 5 char S[maxn]; 6 int n,d[maxn][maxn]; 7 8 bool match(char a, char b){ 9 return (a=='(' && b==')') || (a=='[' && b==']'); 10 } 11 12 int dp(int i,int j){ 13 if(i > j) return 0; 14 if(i==j) return 1; 15 if(d[i][j]>=0) return d[i][j]; 16 d[i][j] = n; 17 if(match(S[i],S[j])) d[i][j] = min(d[i][j],dp(i+1,j-1)); 18 for(int k=i; k<j; k++) 19 d[i][j] = min(d[i][j],dp(i,k)+dp(k+1,j)); 20 return d[i][j]; 21 } 22 23 void print(int i,int j){ 24 if(i > j) return; 25 if(i==j){ 26 if(S[i]=='(' || S[i]==')') printf("()"); 27 else printf("[]"); 28 return; 29 } 30 int ans = dp(i,j); 31 if(match(S[i],S[j]) && ans==dp(i+1,j-1)){ 32 printf("%c",S[i]); 33 print(i+1,j-1); 34 printf("%c",S[j]); 35 return; 36 } 37 38 for(int k=i; k<j; k++) 39 if(ans == dp(i,k)+dp(k+1,j)){ 40 print(i,k); 41 print(k+1,j); 42 return; 43 } 44 } 45 46 void readline(char* S) { 47 fgets(S, maxn, stdin); 48 } 49 50 int main() { 51 int T; 52 53 readline(S); 54 sscanf(S, "%d", &T); 55 readline(S); 56 57 while(T--) { 58 readline(S); 59 n = strlen(S) - 1; 60 memset(d, -1, sizeof(d)); 61 print(0, n-1); 62 printf("\n"); 63 if(T) printf("\n"); 64 readline(S); 65 } 66 return 0; 67 }


浙公网安备 33010602011771号