zoukankan      html  css  js  c++  java
  • 区间DP POJ 1141 Brackets Sequence

    Brackets Sequence
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 29520   Accepted: 8406   Special Judge

    Description

    Let us define a regular brackets sequence in the following way: 

    1. Empty sequence is a regular sequence. 
    2. If S is a regular sequence, then (S) and [S] are both regular sequences. 
    3. If A and B are regular sequences, then AB is a regular sequence. 

    For example, all of the following sequences of characters are regular brackets sequences: 

    (), [], (()), ([]), ()[], ()[()] 

    And all of the following character sequences are not: 

    (, [, ), )(, ([)], ([(] 

    Some sequence of characters '(', ')', '[', and ']' is given. You are to find the shortest possible regular brackets sequence, that contains the given character sequence as a subsequence. Here, a string a1 a2 ... an is called a subsequence of the string b1 b2 ... bm, if there exist such indices 1 = i1 < i2 < ... < in = m, that aj = bij for all 1 = j = n.

    Input

    The input file contains at most 100 brackets (characters '(', ')', '[' and ']') that are situated on a single line without any other characters among them.

    Output

    Write to the output file a single line that contains some regular brackets sequence that has the minimal possible length and contains the given sequence as a subsequence.

    Sample Input

    ([(]

    Sample Output

    ()[()]
        
     1 /*对于DP题目需要记录到底是怎样得到结果的,不一定了可以通过记录信息直接得到,可以选择数组记录其他有用信息,可以写递归来找出最后的答案。*/
     2 #define N 111
     3 #include<iostream>
     4 using namespace std;
     5 #include<cstring>
     6 #include<cstdio>
     7 #define inf (1<<31)-1
     8 int f[N][N],pos[N][N],lens;
     9 char s[N];
    10 void print(int l,int r)/*输出序列的过程*/
    11 {
    12     if(l<=r)/*一定要有这一句,否则对于相邻的‘()’,就会死循环了*/
    13     {
    14         if(l==r)/*能到这一步,说明只能补上括号了*/
    15         {
    16             if(s[l]=='('||s[l]==')') printf("()");
    17             if(s[l]=='['||s[l]==']') printf("[]");
    18         }
    19         else 
    20         {
    21             if(pos[l][r]==-1)/*说明该区间最左括号与最右匹配*/
    22             {
    23                 printf("%c",s[l]);
    24                 print(l+1,r-1);/**/
    25                 printf("%c",s[r]);
    26             }
    27             else 
    28             {
    29                 print(l,pos[l][r]);
    30                 print(pos[l][r]+1,r);
    31             }
    32         }
    33     }
    34 }
    35 int main()
    36 {
    37 //    freopen("bracket.in","r",stdin);
    38 //    freopen("bracket.out","w",stdout);
    39     scanf("%s",s+1);
    40     lens=strlen(s+1);
    41     for(int i=1;i<=lens;++i)
    42       f[i][i]=1;
    43 /*    for(int i=lens-1;i>=1;--i)
    44       for(int j=i+1;j<=lens;++j)
    45       {
    46             f[i][j]=inf;
    47             if(((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']')))
    48               {
    49                   f[i][j]=f[i+1][j-1];
    50                   pos[i][j]=-1;
    51             }
    52                                 
    53             for(int k=i;k<=j-1;++k)
    54             {
    55             if(f[i][j]>f[i][k]+f[k+1][j])
    56             {
    57                     f[i][j]=f[i][k]+f[k+1][j];
    58                     pos[i][j]=k;
    59             }
    60             
    61           }
    62           
    63       }这两种都是可以得出正确答案的,但是我建议使用下面的,对于区间DP,最外层循环最好枚举区间长度,内层枚举区间*/
    64     for(int k=1;k<lens;++k)
    65       for(int i=1,j=i+k;j<=lens&&i<=lens;++j,++i)
    66       {
    67             f[i][j]=inf;
    68             if((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']'))
    69               {
    70                   f[i][j]=f[i+1][j-1];
    71                   pos[i][j]=-1;
    72             }
    73                  /*不要加else,因为即使当前区间的最左和最右匹配,也不一定比放弃他们匹配优*/
    74             for(int k=i;k<=j-1;++k)
    75             {
    76             if(f[i][j]>f[i][k]+f[k+1][j])
    77             {
    78                     f[i][j]=f[i][k]+f[k+1][j];
    79                     pos[i][j]=k;
    80             }
    81             
    82           }
    83           
    84       }
    85     print(1,lens);
    86     printf("
    ");/*坑爹的POJ,没有这句,一直没对*/
    87     //fclose(stdin);fclose(stdout);
    88     return 0;
    89 }
  • 相关阅读:
    八、分组
    七、select使用
    六、SQL基础应用
    五、修改MySQL密码
    side Effect
    js函数式编程
    React生命周期
    Portals
    git使用技巧
    函数式编程
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5496177.html
Copyright © 2011-2022 走看看