POJ

来源:互联网 发布:python ftplib 编辑:程序博客网 时间:2024/06/05 07:22

Brackets Sequence

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

()[()]



题意:给你一堆括号,要你补最少的括号,使其形成的括号串最短。


解题思路:参考最小括号匹配那题

http://blog.csdn.net/lzc504603913/article/details/76944119

那题输出最小匹配数,这题刚好相反,你要补最少的括号,使其可以完全匹配,思路类似,dp[i][j]存i到j这个区间内需要补的最少括号,如果s[i]==s[j],那么不用补,然后从中间枚举,并记录截断的位置,用于输出。详见代码注释。



#include<iostream>#include<memory.h>#include<string>using namespace std;string str;int dp[115][115];//i到j这个区间需要补最少多少个括号使得符合题意int jie[115][115];//i到j这个区间是从哪里开始截断的//递归输出void shuchu(int l,int r){    if(l>r)        return;        //如果区间大小为1,那么就看看是什么括号,就输出哪种    if(l==r){        if(str[l]=='('||str[r]==')')            cout<<"()";        else            cout<<"[]";            }    else{        //如果两边可以匹配,那么该输出啥就输出啥,然后看看中间有没有截断        if(jie[l][r]==-1){            cout<<str[l];            shuchu(l+1,r-1);            cout<<str[r];        }        else{            //如果不匹配,就从截断的两边输出            shuchu(l,jie[l][r]);            shuchu(jie[l][r]+1,r);        }    }}int main(){        cin>>str;                memset(dp,0,sizeof(dp));            for(int i=0;i<str.size();i++){        dp[i][i]=1;//大小为1的区间肯定要补1个    }            //枚举区间长度,必须要从小到大枚举    for(int len=2;len<=str.size();len++){                //l,r为左右标记,两个标记不断地右移        for(int l=0,r=len-1;r<str.size();l++,r++){                                    if((str[l]=='('&&str[r]==')')||(str[l]=='['&&str[r]==']')){                dp[l][r]=dp[l+1][r-1];                jie[l][r]=-1;//本来就匹配,不需要截断时为-1            }            else                dp[l][r]=0x7fffffff;//如果不匹配,置为无限大,方便后面取最小                                    //枚举中间            for(int z=l;z<r;z++){                //如果从这里截开可以使得补最少的括号,那么就从这里截,记录截的位置                if(dp[l][r]>dp[l][z]+dp[z+1][r]){                    dp[l][r]=dp[l][z]+dp[z+1][r];                    jie[l][r]=z;                }            }        }            }        shuchu(0,str.size()-1);    cout<<endl;        return 0;}






原创粉丝点击