1. 程式人生 > >POJ 1141 Brackets Sequence

POJ 1141 Brackets Sequence

lar == and style 一個 clas space file 空串

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.空序列是合法的。
2.如果s是合法的,那麽(s)和[s]也是合法的。
3.如果A和B都是合法的,那麽AB也是合法的。

分析
設串S至少需要增加d(S)個括號,轉移如下:
1.如果S形如(S`)或者[S`],轉移到d(S`)。
2.如果S至少有兩個字符,則可以分為AB,轉移到d(A)+d(B)。
邊界是:當S為空串,d(S)=0;為單字符時,d(S)=1。
註意:不管S是否滿足第一種情況,都需要嘗試第二種情況,否則"[][]"會轉移到"]["。
由此,定義dp[i][j]為字符串第i個字符到第j個字符變成合法的至少需要添加幾個括號。
另外,本題還要輸出構造的合法串,於是用個二維數組記錄切割的位置,最後遞歸輸出。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include <queue>
#include <vector>
#include<bitset>
#include<map>
#include<deque>
using namespace std;
typedef long long LL;
const int maxn = 1e4+5;
const int mod = 77200211+233;
typedef pair<int,int> pii;
#define X first
#define Y second
#define pb push_back
//#define mp make_pair
#define ms(a,b) memset(a,b,sizeof(a))
const int inf = 0x3f3f3f3f;
#define lson l,m,2*rt
#define rson m+1,r,2*rt+1
typedef long long ll;
#define N 100010
//dp[i][j]表示區間i到j需要的最少括號數
int dp[105][105],pos[105][105];
char s[105];

bool match(char a,char b){
    if((a==(&&b==)) || (a==[&&b==])) return true;
    return false;
}
void Print(int i,int j){
    if(i>j) return;
    if(i==j){
        if(s[i]==(||s[i]==)) printf("()");
        else printf("[]");
        return;
    }
    if(pos[i][j]==-1){
        if(s[i]==(){
            printf("(");
            Print(i+1,j-1);
            printf(")");
        }else{
            printf("[");
            Print(i+1,j-1);
            printf("]");
        }
    }else{
        Print(i,pos[i][j]);
        Print(pos[i][j]+1,j);
    }
}
int main(){
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif // LOCAL
    while(gets(s+1)){
        int len = strlen(s+1);
//        cout<<s[len]<<endl;
        ms(dp,0);
        for(int i=1;i<=len;i++) dp[i][i]=1;

        for(int p=2;p<=len;p++){//區間長度
            for(int i=1;i+p-1<=len;i++){
                int j=i+p-1;
                dp[i][j]=2*len;
                if(match(s[i],s[j])){
                    dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
                }
                pos[i][j]=-1;
                for(int k=i;k<j;k++){
                    int temp=dp[i][k]+dp[k+1][j];
                    if(temp<dp[i][j]){
                        dp[i][j]=temp;
                        pos[i][j]=k;
                    }
                }
            }
        }
        Print(1,len);
        puts("");
//        cout<<dp[1][len]<<endl;
    }
    return 0;
}

 

POJ 1141 Brackets Sequence