zoukankan      html  css  js  c++  java
  • poj 1141 Brackets Sequence(区间DP)

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

    转载:http://blog.csdn.net/lijiecsu/article/details/7589877

    定义合法的括号序列如下:

    1 空序列是一个合法的序列

    2 如果S是合法的序列,则(S)和[S]也是合法的序列

    3 如果A和B是合法的序列,则AB也是合法的序列

    例如:下面的都是合法的括号序列

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

    下面的都是非法的括号序列

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

    给定一个由'(',  ')',  '[', 和 ']' 组成的序列,找出以该序列为子序列的最短合法序列。

    d[i][j]为输入序列从下标i到下标j最少需要加多少括号才能成为合法序列。0<=i<=j<len (len为输入序列的长度)。

    c[i][j]为输入序列从下标i到下标j的断开位置,如果没有断开则为-1。

    当i==j时,d[i][j]为1

    当s[i]=='(' && s[j]==')' 或者 s[i]=='[' && s[j]==']'时,d[i][j]=d[i+1][j-1]

    否则d[i][j]=min{d[i][k]+d[k+1][j]} i<=k<j ,  c[i][j]记录断开的位置k

    采用递推方式计算d[i][j]

     

    输出结果时采用递归方式输出print(0, len-1)

    输出函数定义为print(int i, int j),表示输出从下标i到下标j的合法序列

    当i>j时,直接返回,不需要输出

    当i==j时,d[i][j]为1,至少要加一个括号,如果s[i]为'(' 或者')',输出"()",否则输出"[]"

    当i>j时,如果c[i][j]>=0,说明从i到j断开了,则递归调用print(i, c[i][j]);和print(c[i][j]+1, j);

                    如果c[i][j]<0,说明没有断开,如果s[i]=='(' 则输出'('、 print(i+1, j-1); 和")"  否则输出"[" print(i+1, j-1);和"]"

    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    int dp[107][107];
    int c[107][107];
    char ch[107];
    int len ;
    
    void mydp()
    {
        memset(dp,0,sizeof(dp));
        memset(c,0,sizeof(c));
    
        int i,j,k,l;
        for(i = 0; i < len; i++) dp[i][i] = 1;
        int min;
        for(l = 1; l < len; l++)
            for(i = 0; i+l < len; i++)
                {
                    j = i+l;
                    min=dp[i][i] + dp[i+1][j];
                    c[i][j] = i;
                    for(k = i+1; k < j; k++)
                    {
                        if(dp[i][k]+dp[k+1][j] < min)
                        {
                            min = dp[i][k] + dp[k+1][j];
                            c[i][j] = k;
                        }
                    }
                    dp[i][j] = min;
    
                    if( (ch[i] == '(' && ch[j] == ')') || (ch[i] == '[' && ch[j] == ']') )
                    {
                        if(dp[i+1][j-1] < min){
                            dp[i][j] = dp[i+1][j-1];
                            c[i][j] = -1;
                        }
                    }
                }
    }
    
    void print(int i,int j)
    {
        if(i > j) return;
        if(i == j)
        {
           if(ch[i]== '(' || ch[i] == ')') printf("()");
           else printf("[]");
        }
        else
        {
            if(c[i][j] >= 0)
            {
                print(i,c[i][j]);
                print(c[i][j]+1,j);
            }
            else
            {
                if(ch[i] == '(')
                  {
                      printf("(");
                      print(i+1,j-1);
                      printf(")");
                  }
                else
                {
                    printf("[");
                    print(i+1,j-1);
                    printf("]");
                }
            }
        }
    }
    
    void printdp()
    {
        for(int i = 0; i < len; i++)
            {for(int j = 0; j < len; j++)
            printf("%d ",dp[i][j]);
            printf("
    ");}
             printf("
    ");
             for(int i = 0; i < len; i++)
            {for(int j = 0; j < len; j++)
            printf("%d ",c[i][j]);
            printf("
    ");}
    }
    int main()
    {
            scanf("%s",ch);
            len = strlen(ch);
            mydp();
          //  printdp();
            print(0,len-1);
            printf("
    ");
    
        return 0;
    }
    

      

  • 相关阅读:
    excel打印预览后整个表格中按页显示虚线,打印时就会打印很多页
    4.8 自定义下拉菜单模式Spinner与setDropDownViewResource
    1.2Matlab基本语法和基本操作.
    CTime类的一个BUG
    【转载】PE_Info 之DIY
    ubuntu使用记录
    反VM测试成功
    获取MAC地址
    【转载】秒到oep,支持所有壳,包括vmp
    【转载】Make your owner PE Protector
  • 原文地址:https://www.cnblogs.com/yyroom/p/3738654.html
Copyright © 2011-2022 走看看