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("
");
66         if(T) printf("
");
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("
");
63     if(T) printf("
");
64     readline(S);
65   }
66   return 0;
67 }
原文地址:https://www.cnblogs.com/yxg123123/p/6827745.html