Brackets Sequence (poj 1141)

C - Brackets Sequence
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u
Appoint description: 

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

()[()]



题意:

给出一个由 ( ) [ ] 四种符号组成的串,问要把这个串变成括号匹配串后的最短串是什么样。


struct node

{

int t;

string now;

}

用 dp[i][j].t 来记录区间 i~j 所需要的最小数目,dp[i][j].now 记录区间 i~j 这个区间变成匹配区间之后的样子。


若 s[i] == s[j] 那么 dp[i][j].t = min(dp[i][j].t,dp[i+1][j-1].t);


枚举i~j中间的断点k 有 dp[i][j].t = min(dp[i][j].t , dp[i][k].t + dp[k+1][j].t);


然后对于每次转移的由来将对应区间的 now 做出对应改变。


注意坑点是虽然题目没说,但是输入的字符串可能是包含空格的(估计是标程都错了导致样例有问题)。对于空格也应该输出一对括号来匹配。


#include"iostream"
#include"cstring"
#include"cstdio"
#include"algorithm"
#include"string"

#define INF 0x7fffffff

using namespace std;

struct node
{
    int t;
    string now;
};

char sc[105];
string ss;
node dp[105][105];

bool check(char a,char b)
{
    if(a == '(' && b == ')') return true;
    if(a == '[' && b == ']') return true;
    return false;
}

void init(int siz)
{
    for(int i = 0;i < siz;i++)
    {
        for(int j = i;j < siz;j++)
        {
            dp[i][j].now = "";
            dp[i][j].t = INF;
        }
    }

    for(int i = 0;i < siz;i++)
    {
        dp[i][i].t = 1;
        if(ss[i] == '(' || ss[i] == ')')
            dp[i][i].now = "()";
        else dp[i][i].now = "[]";
    }
}

int main(void)
{
    while(gets(sc))
    {
        ss = sc;
        int siz = ss.size();

        init(siz);

        for(int i = siz-1;i >= 0;i--)
        {
            for(int j = i+1;j < siz;j++)
            {
                if(check(ss[i],ss[j]))
                {
                    if(dp[i+1][j-1].t < dp[i][j].t)
                    {
                        dp[i][j].t = dp[i+1][j-1].t;
                        dp[i][j].now = ss[i] + dp[i+1][j-1].now + ss[j];
                    }
                }

                for(int k = i;k < j;k++)
                {
                    if(dp[i][j].t > dp[i][k].t + dp[k+1][j].t)
                    {
                        dp[i][j].t = dp[i][k].t + dp[k+1][j].t;
                        dp[i][j].now = dp[i][k].now + dp[k+1][j].now;
                    }
                }
            }
        }

        cout << dp[0][siz-1].now << endl;
    }
    return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值