1183. Brackets Sequence
Time limit: 1.0 second
Memory limit: 64 MB
Memory limit: 64 MB
Let us define a regular brackets sequence in the following way:
- Empty sequence is a regular sequence.
- If S is a regular sequence, then (S) and [S] are both regular sequences.
- 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 a
1a
2...a
nis called a subsequence of the string b
1b
2...b
m, if there exist such indices 1 ≤ i
1 < i
2 < ... < i
n ≤ m, that a
j=b
ij for all 1 ≤ j ≤ n.
Input
The input contains at most 100 brackets (characters '(', ')', '[' and ']') that are situated on a single line without any other characters among them.
Output
Write 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 | output |
---|---|
([(] | ()[()] |
Problem Author: Andrew Stankevich
Problem Source: 2001-2002 ACM Northeastern European Regional Programming Contest
Problem Source: 2001-2002 ACM Northeastern European Regional Programming Contest
Difficulty: 209
Printable version
Submit solution
Discussion (22)
All submissions (8722) All accepted submissions (2762) Solutions rating (2007)
题目 在黑书的例1.5.1只是多了递归输出操作,只需要记忆一下就可以啦。
题目已经给出了dp的思路;
//dp[i][j] : 代表si....sj之间最小的匹配括号数;
//op[i][j] : 0 - 代表i == j需要自身配对 ; -1 : i和j匹配; 其他:就是(i k)-(k j)最小匹配;
代码:
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e2+7;
char s[maxn];
//dp[i][j] : 代表si....sj之间最小的匹配括号数;
//op[i][j] : 0 - 代表i == j需要自身配对 ; -1 : i和j匹配; 其他:就是(i k)-(k j)最小匹配;
int len, dp[maxn][maxn], op[maxn][maxn];
void print(int i, int j)
{
if(i>j) return;//注意判错
if(op[i][j]>0){
print(i,op[i][j]);
print(op[i][j]+1,j);
return;
}
if(!op[i][j]){
if(s[i]=='('||s[i]==')') printf("()");
else printf("[]");
return;
}
printf("%c",s[i]);
print(i+1,j-1);
printf("%c",s[j]);
return;
}
int main()
{
//freopen("in.txt", "r", stdin);
while(~scanf("%s", s+1))
{
len = strlen(s+1);
for(int i = len; i >= 1; i--)
{
for(int j = i; j <= len; j++)
{
if(i == j)
{
dp[i][j] = 1; op[i][j] = 0;
continue;
}
int temp = i, ans = INF;
for(int k = i; k < j; k++)
{
if(dp[i][k]+dp[k+1][j] < ans) {
ans = dp[i][k]+dp[k+1][j];
temp = k;
}
}
dp[i][j] = ans;
op[i][j] = temp;
if((s[i] == '('&&s[j] == ')')||(s[i] == '['&&s[j] == ']'))
{
if((i+1) == j) dp[i][j] = 0, op[i][j] = -1;
else if(dp[i+1][j-1]<dp[i][j]) dp[i][j] = dp[i+1][j-1], op[i][j] = -1;
}
}
}
print(1, len);
printf("\n");
}
return 0;
}