zoukankan      html  css  js  c++  java
  • ZOJ1463:Brackets Sequence(间隙DP)

    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.


    This problem contains multiple test cases!

    The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.

    The output format consists of N output blocks. There is a blank line between output blocks.


    Sample Input

    1

    ([(]


    Sample Output

    ()[()] 


    关键在于输入与输出格式。神坑。

    区间dp,dp[i][j]表示 区间 i 到j之间的匹配数,区间两端的 字符能否够刚好匹配,若能够匹配 状态转移就多了一个 dp[i][j] = max(dp[i][k]+dp[k+1][j],dp[i+1][j-1]+1),若不能匹配就是dp[i][j] = max(dp[i][j],dp[i][k]+dp[k+1][j]);

    若是两端能够匹配的,并且两端匹配了导致的dp值最大那么就标记一下。mark[i][j] = -1,否则 就mark[i][j] = k,这样把全部区间都dp一遍,回头再用DFS寻找。若是两端匹配导致值最大的 那么就直接输出这个字符标记一下,继续往更小的区间去搜索,否则 就分开两个区间搜索 [i,k]        [k+1,j]


    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define up(i,x,y) for(i=x;i<=y;i++)
    #define down(i,x,y) for(i=x;i>=y;i--)
    #define mem(a,b) memset(a,b,sizeof(a))
    #define w(a) while(a)
    char str[105];
    int t,len,dp[105][105],mark[105][105],pos[105];
    void dfs(int i,int j)
    {
        if(mark[i][j]==-1)
        {
            pos[i]=pos[j]=1;
            dfs(i+1,j-1);
        }
        else if(mark[i][j]>=0)
        {
            dfs(i,mark[i][j]);
            dfs(mark[i][j]+1,j);
        }
        return;
    }
    int main()
    {
        int l,i,j,k;
        scanf("%d%*c%*c",&t);
        while(t--)
        {
            gets(str);
            len=strlen(str);
            if(!len)
            {
                printf("
    ");
                if(t)
                printf("
    ");
                continue;
            }
            up(i,0,len-1)
            up(j,0,len-1)
            {
                mark[i][j]=-2;
                dp[i][j]=0;
            }
            mem(pos,0);
            i=j=l=0;
            w(l<len)
            {
                if(i==j)
                {
                    i++,j++;
                    if(j==len)
                        i=0,l++,j=l;
                    continue;
                }
                if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))
                {
                    up(k,i,j-1)
                    {
                        if(dp[i][j]<dp[i][k]+dp[k+1][j])
                        {
                            mark[i][j]=k;
                            dp[i][j]=dp[i][k]+dp[k+1][j];
                        }
                    }
                    if(dp[i][j]<dp[i+1][j-1]+1)
                    {
                        mark[i][j]=-1;
                        dp[i][j]=dp[i+1][j-1]+1;
                    }
                }
                else
                {
                    up(k,i,j-1)
                    {
                        if(dp[i][j]<dp[i][k]+dp[k+1][j])
                        {
                            mark[i][j]=k;
                            dp[i][j]=dp[i][k]+dp[k+1][j];
                        }
                    }
                }
                i++,j++;
                if(j==len)
                {
                    l++;
                    i=0;
                    j=l;
                }
            }
            dfs(0,len-1);
            up(i,0,len-1)
            {
                if(pos[i]==1)
                    printf("%c",str[i]);
                else if(str[i]=='('||str[i]==')')
                    printf("()");
                else
                    printf("[]");
            }
            printf("
    ");
            if(t)
            {
                printf("
    ");
                getchar();
            }
        }
    
        return 0;
    }
    


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    redis中文API
    基于redis的分布式锁
    redis安装使用配置
    windows常用命令
    curl命令详解
    linux远程连接
    memcache在大型网站的应用策略
    缓存使用的一些注意事项
    记录memcache分布式策略及算法
    U盘安装Centos7.0图解
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4836359.html
Copyright © 2011-2022 走看看