zoukankan      html  css  js  c++  java
  • [ACM] poj 1141 Brackets Sequence (动态规划)

    Brackets Sequence
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 23884   Accepted: 6727   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

    ()[()]

    Source

    参考资料:

    http://www.cnblogs.com/android-html5/archive/2010/05/30/2534035.html

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

    dp[i][j]更新的顺序

    假设字符串的长度为6

    (0,1) (1,2) (2,3) (3,4) (4,5)

    (0,2) (1,3) (2,4) (3,5)

    (0,3) (1,4) (2,5)

    (0,4) (1,5)

    (0,5)

    任何可能的区间都在里面,而且区间长度由小到大,这也符合动规把大问题转化为小问题的思想。

    代码:

    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    using namespace std;
    const int maxn=250;
    const int inf=0x7fffffff;
    char str[maxn];
    int dp[maxn][maxn],ps[maxn][maxn];
    //dp[i][j]代表串从i到j需要添加几个字符才能合法,ps[i][j],记录的从i到j在哪里断成两部分
    int len;
    
    void print(int i,int j)//递归输出
    {
        if(i>j)
            return;
        if(i==j)
        {
            if(str[i]=='('||str[i]==')')
                cout<<"()";
            else
                cout<<"[]";
        }
        else if(ps[i][j]==-1)//从i到j括号匹配
        {
            cout<<str[i];
            print(i+1,j-1);
            cout<<str[j];
        }
        else//不匹配分成两部分输出
        {
            print(i,ps[i][j]);
            print(ps[i][j]+1,j);
        }
    }
    
    int main()
    {
        cin>>str;
        len=strlen(str);
        memset(dp,0,sizeof(dp));
        for(int i=0;i<len;i++)
            dp[i][i]=1;
        for(int k=1;k<len;k++)//区间从小到大
            for(int i=0;i+k<len;i++)
        {
            int j=i+k;
            dp[i][j]=inf;
            if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))
            {
                dp[i][j]=dp[i+1][j-1];
                ps[i][j]=-1;//括号匹配,不用添加另外的括号
            }
            for(int mid=i;mid<j;mid++)//看是否能划分为两部分
            {
                if(dp[i][j]>(dp[i][mid]+dp[mid+1][j]))
                {
                    dp[i][j]=dp[i][mid]+dp[mid+1][j];
                    ps[i][j]=mid;//mid为串i到j区间断开的位置
                }
            }
        }
        print(0,len-1);
        cout<<endl;
        return 0;
    }
    


     

  • 相关阅读:
    数据库表结构变动发邮件脚本
    .net程序打包部署
    无法登陆GitHub解决方法
    netbeans 打包生成 jar
    第一次值班
    RHEL6 纯命令行文本界面下安装桌面
    C语言中格式化输出,四舍五入类型问题
    I'm up to my ears
    How to boot ubuntu in text mode instead of graphical(X) mode
    the IP routing table under linux@school
  • 原文地址:https://www.cnblogs.com/sr1993/p/3697755.html
Copyright © 2011-2022 走看看