POJ 1141 Brackets Sequence(括号匹配二)

题目链接:http://poj.org/problem?id=1141

题目大意:给你一串字符串,让你补全括号,要求补得括号最少,并输出补全后的结果。

解题思路:

开始想的是利用相邻子区间,即dp[i+1][j]之类的方法求,像是求回文串的区间DP一样。然后花了3个多小时,GG。。。

错误数据:

(())(]][[)
my:6 (()()()[][][][])
ans:4 (())([][][][])
括号匹配跟回文串不同,并不能通过dp[i+1][j]或者dp[i][j-1]推得dp[i][j],可能是因为回文串必须满足称性质。
而括号匹配可能可以划分成连个任意大小的子区间而没有影响。

然后正解跟括号匹配一差不多,因为你想啊,括号匹配一求的是最多的括号对数,把原字符串长度减一下最大括号匹配数,不就是最少需要补全的括号数了嘛,我竟然想了这么久。。。

设dp[i][j]为[i,j]最少需要补齐的括号数,得到状态转移方程:

if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']'){
  dp[i][j]=dp[i+1][j-1];
}
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]),(i=<k<j)

然后,如果dp[i][j]由dp[i][k]和dp[i][k+1]组成,则记录path[i][j]=k,否则记为-1,最后递归输出一下就行了。

注意:输入用while(~scanf("%s",s))会错,不知道为什么

代码

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #include<set>
10 #include<map>
11 #include<stack>
12 #include<string>
13 #define lc(a) (a<<1)
14 #define rc(a) (a<<1|1)
15 #define MID(a,b) ((a+b)>>1)
16 #define fin(name)  freopen(name,"r",stdin)
17 #define fout(name) freopen(name,"w",stdout)
18 #define clr(arr,val) memset(arr,val,sizeof(arr))
19 #define _for(i,start,end) for(int i=start;i<=end;i++)
20 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
21 using namespace std;
22 typedef long long LL;
23 const int N=1e3+5;
24 const int INF=0x3f3f3f3f;
25 const double eps=1e-10;
26 
27 int dp[N][N],path[N][N];
28 char str[N];
29 
30 void print(int l,int r){
31     if(l>=r){
32         if(l==r){
33             if(str[l]==')'||str[l]=='(')
34                 printf("()");
35             if(str[l]==']'||str[l]=='[')
36                 printf("[]");
37         }
38         return;
39     }
40     if(path[l][r]==-1){
41         printf("%c",str[l]);
42         print(l+1,r-1);
43         printf("%c",str[r]);
44     }
45     else{
46         int k=path[l][r];
47         print(l,k);
48         print(k+1,r);
49     }
50 }
51 
52 int main(){
53     while(gets(str)){
54         memset(path,-1,sizeof(path));
55         int n=strlen(str);
56         for(int i=0;i<=n;i++){
57             dp[i][i]=1;
58         }
59         for(int len=1;len<n;len++){
60             for(int i=0;i+len<n;i++){
61                 int j=i+len;
62                 dp[i][j]=INF;
63                 if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']'){
64                     dp[i][j]=dp[i+1][j-1];
65                 }
66                 for(int k=i;k<j;k++){
67                     if(dp[i][j]>dp[i][k]+dp[k+1][j]){
68                         dp[i][j]=dp[i][k]+dp[k+1][j];
69                         path[i][j]=k;       
70                     }
71                 }
72             }
73         }
74         print(0,n-1);
75         printf("\n");
76     }
77     return 0;
78 }

 附上写错的代码做个纪念,毕竟写了这么久也是有感情的。。。

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<cctype>
  4 #include<cstring>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<vector>
  8 #include<queue>
  9 #include<set>
 10 #include<map>
 11 #include<stack>
 12 #include<string>
 13 #define lc(a) (a<<1)
 14 #define rc(a) (a<<1|1)
 15 #define MID(a,b) ((a+b)>>1)
 16 #define fin(name)  freopen(name,"r",stdin)
 17 #define fout(name) freopen(name,"w",stdout)
 18 #define clr(arr,val) memset(arr,val,sizeof(arr))
 19 #define _for(i,start,end) for(int i=start;i<=end;i++)
 20 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
 21 using namespace std;
 22 typedef long long LL;
 23 const int N=1e3+5;
 24 const int INF=0x3f3f3f3f;
 25 const double eps=1e-10;
 26 
 27 int dp[N][N],path[N][N];
 28 char str[N];
 29 int flag[N];
 30 void print(int x,int y){
 31 
 32     if(x>=y){
 33         if(x==y)
 34             flag[x]=1;
 35         return;
 36     }
 37     int t=path[x][y];
 38     if(t==1){
 39         flag[x]=1;
 40         print(x+1,y);
 41     }
 42     if(t==2){
 43         flag[y]=1;
 44         print(x,y-1);
 45     }
 46     if(t==3){
 47         print(x+1,y-1);
 48     }
 49     if(t==4){
 50         print(x+2,y);
 51     }
 52     if(t==5){
 53         print(x,y-2);
 54     }
 55 }
 56 //[)[)]]
 57 int main(){
 58     while(gets(str)){
 59        int n=strlen(str);
 60        memset(dp,0,sizeof(dp));
 61        memset(path,-1,sizeof(path));
 62        memset(flag,0,sizeof(flag));
 63        for(int i=1;i<=n;i++){
 64             dp[i][i]=1;
 65         }
 66         for(int len=1;len<n;len++){
 67             for(int i=0;i+len<n;i++){
 68                 int j=i+len;
 69                 dp[i][j]=INF;
 70                 int t1=dp[i+1][j]+1,t2=dp[i][j-1]+1,t3=dp[i+1][j-1],t4=dp[i+2][j],t5=dp[i][j-2];
 71                 dp[i][j]=min(dp[i][j],t1);
 72                 dp[i][j]=min(dp[i][j],t2);
 73                 if(min(t1,t2)==t1)
 74                     path[i][j]=1;
 75                 else
 76                     path[i][j]=2;
 77                 if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']'&&t3<dp[i][j]){
 78                     dp[i][j]=t3;
 79                     path[i][j]=3;
 80                 }
 81                 if(str[i]=='('&&str[i+1]==')'||str[i]=='['&&str[i+1]==']'&&t4<dp[i][j]){
 82                     dp[i][j]=t4;
 83                     path[i][j]=4;
 84                 }
 85                 if(str[j]==')'&&str[j-1]=='('||str[j]==']'&&str[j-1]=='['&&t5<dp[i][j]){
 86                     dp[i][j]=t5;
 87                     path[i][j]=5;
 88                 }
 89                 if(len==5)
 90                     cout<<"i="<<i<<" j="<<j<<" "<<dp[i][j]<<" "<<path[i][j]<<endl;
 91             }
 92         }
 93         //printf("%d\n",dp[0][n-1]);
 94         print(0,n-1);
 95         for(int i=0;i<n;i++){
 96             if(flag[i]){
 97                 if(str[i]=='(')
 98                     cout<<"()";
 99                 if(str[i]==')')
100                     cout<<"()";
101                 if(str[i]=='[')
102                     cout<<"[]";
103                 if(str[i]==']')
104                     cout<<"[]";
105             }
106             else
107                 cout<<str[i];
108         }
109         printf("\n");
110     }
111     return 0;
112 }

 

posted @ 2018-04-15 03:37  Yeader  阅读(173)  评论(0编辑  收藏  举报