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.
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的方式,假设序列长度是100,则我们把序列分为0~j,j+1~100,而j的取值,就是最佳决策,所以我们我们要求的就是一张最佳决策表,这里面的表值就是J的值以及需要添加的括号个数,这张表我们用2个二维数组表示
Dp[i][j]
Flag[i][j]
其中Dp存储的是从i到j该子序列需要插入的括号数的最优值
Flag存储的是上文提到的J值
Flag[i][j]存在的意义很清楚那么Dp呢?,Dp存在的意义主要是计算过程中的判断,我们需要找到最佳的J值意味着我们需要找到Dp值最小的J。
所以最终的代码如下:
其中Match用于计算Dp和Flag,show则用于显示
//AC 272K 0MS #include <iostream> using namespace std; #define MAX 105 #define INIT 1e9 int Dp[MAX][MAX];//最优决策表,存储i到j需要添加的括号个数值 int Flag[MAX][MAX];//表示从i到j需不需要分开来处理,如果需要那么该值就是需要拆分的点,该值代表的点归于左边 char s[MAX];//原数据 void Match(int len) { //给表中i=j的项赋值 for (int i=0; i<len; i++) { Dp[i][i] = 1; } //求出Dp的值,只需要求出 头<尾 的情况,头是i,尾是len-j 所以循环的条件如下 for (int j=1; j<len; j++) for (int i=0; i<len-j; i++) { char Right = s[i+j]; char Left = s[i]; Dp[i][i+j] = INIT;//初始化值,防止后续调用对比时出问题 //因为题意中有(S)= [S] = S,所以我们需要下面这一步 if ((Left == '('&&Right == ')')||(Left == '['&&Right == ']')) { Dp[i][i+j] = Dp[i+1][i+j-1]; Flag[i][i+j] = -1; } //DP核心 基于当前的结果,寻找最佳决策的过程 for(int k=i; k<i+j; k++) { if (Dp[i][i+j] > Dp[i][k] + Dp[k+1][i+j]) { Flag[i][i+j] = k; Dp[i][i+j] = Dp[i][k] + Dp[k+1][i+j]; } } } } void show(int i, int j) { if (i > j) return; if (i == j)//通过不断的递归,最终细分的子序列的添加动作都是在这里 { if (s[i] == '('||s[i] == ')') cout<<"()"; else cout<<"[]"; } else { if (Flag[i][j] == -1)//表示i到j这一段首尾是配对的,并且此时此刻不需要分成2段计算 { cout<<s[i]; show(i+1,j-1); cout<<s[j]; } else//要分成2段处理 { show(i, Flag[i][j]); show(Flag[i][j]+1, j); } } } int main() { cin>>s; int len = strlen(s); Match(len); show(0, len-1); cout<<endl; return 0; }