POJ1141 ZOJ1463 Brackets Sequence【區間dp】

MissZhou要努力發表於2016-04-26

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

()[()]

題意十分簡單,然而卡了我一上午,也怪自己狀態不好,學成這樣還想著玩?!

給定字串,問最終匹配成的字串【】() 開始還以為是像poj2955Brackets【區間dp 括號匹配】 這樣的,結果是難了好多==

首先求出的dp[][]陣列意義是區間內最少新增的括號數量,pos[][]表示區間內加括號位置,-1表示i,j匹配。據說是遞迴時間太慢,下面的遞推求dp[][]。具體看程式碼吧,寢室要關門了==


#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[102][102],len,n;
char str[105];
int pos[109][109];
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
void cal()
{
    memset(f,0,sizeof(f));
    for(int i=1;i<=len;i++) f[i][i]=1;
    int tmp;
    for(int p=1;p<=len;p++)
    {
        for(int i=1;i+p<=len;i++)
        {
            int j=i+p;
            f[i][j]=0x3f3f3f3f;
            if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))
            {
                tmp=f[i+1][j-1];
                if(tmp<f[i][j])f[i][j]=tmp;
            }
            pos[i][j]=-1;
            for(int k=i;k<j;k++)
            {
                tmp=f[i][k]+f[k+1][j];
                if(f[i][j]>tmp)
                {
                    f[i][j]=tmp;
                    pos[i][j]=k;
                }
            }
        }
    }

}

void print(int l,int r)
{
    if(l>r)return;
    if(l==r)
    {
        if(str[l]=='('||str[l]==')')printf("()");
        else printf("[]");
        return;
    }
    if(pos[l][r]==-1)
    {
        if(str[l]=='(')
        {
            printf("(");
            print(l+1,r-1);
            printf(")");
        }
        else
        {
            printf("[");
            print(l+1,r-1);
            printf("]");
        }
    }
    else
    {
        print(l,pos[l][r]);
        print(pos[l][r]+1,r);
    }
}
int main()
{
   // freopen("cin.txt","r",stdin);
    scanf("%s",str);
    {
       // if(strcmp(str,"end")==0) break;
        len=strlen(str);
        for(int i=len;i>0;i--) str[i]=str[i-1];
       // printf("%s",str);
        cal();
        print(1,len);
        puts("");
    }
    return 0;
}

相關文章