区间dp]POJ1141 Brackets Sequence

POJ 1141 Brackets Sequence

原题链接http://poj.org/problem?id=1141


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

()[()]

区间dp。。


#include <iostream>
#include <cstring>
using namespace std;
string sub;
int s;
int dp[100][100];
int c[100][100];
void print (int i,int j){
    if (i>j) return;
    if (i==j){
        if (sub[i]=='(' || sub[i]==')') cout << "( ) ";
        else cout << "[ ] ";
    }
    else{
        if (c[i][j]>=0){
            print(i,c[i][j]);
            print(c[i][j]+1,j);
        }
        else{
            if (sub[i]=='('){
                cout << "( ";
                print (i+1,j-1);
                cout << ") ";
            }
            else{
                cout << "[ ";
                print (i+1,j-1);
                cout << "] ";
            }
        }
    }
}
int main() {
    cin >> sub;
    s=(int) sub.size();
    for (int i=0;i<s;i++) dp[i][i]=1;
    for (int i=0;i<s;i++){
        for (int j=0;j<s;j++)
            c[i][j]=-1;
    }
    
    for (int l=1;l<s;l++){
        for (int i=0;i+l<s;i++){
            int j = i+l;
            //断开
            c[i][j]=i;
            int minimum = dp[i][i]+dp[i+1][j];
            int k = i+1;
            while (k<j){
                if (minimum > dp[i][k]+dp[k+1][j]){
                    minimum =dp[i][k]+dp[k+1][j];
                    c[i][j] = k;
                }
                k++;
            }
            dp[i][j] = minimum;
            if ((sub[i]=='(' && sub[j]==')')||(sub[i]=='['&&sub[j]==']')){
                if (dp[i+1][j-1]<minimum){ // 没有断开
                    dp[i][j] = dp[i+1][j-1];
                    c[i][j] = -1;
                }
            }
        }
    }
    
    print(0,s-1);
    cout << endl;
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值