[poj P1141] Brackets Sequence

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[poj P1141] Brackets Sequence相关的知识,希望对你有一定的参考价值。

[poj P1141] Brackets Sequence

Time Limit: 1000MS   Memory Limit: 65536K   Special Judge

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

()[()]

Source

Northeastern Europe 2001

括号匹配的变形题。

这题的范围,非常的适合区间dp。

那么我们来设计一个dp。设f[i][j]为将原串中i~j全部匹配好需要增加的字符数量。

则:

先赋值正无穷。

对于j-i+1==1 ---> f[i][j]=1

对于j-i+1==2 ---> f[i][j]=cmp(a[i],a[j])?0:2

对于j-i+1>=3 ---> f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]),if (cmp(a[i],a[j])) f[i][j]=min(f[i][j],f[i+1][j-1])

其中cmp代表两个字符是否匹配。

那么这样,就轻松计算出了f[1][n]。

这一题要让我们输出方案。

一般dp的题都可以用dfs递归输出方案。

具体实现应该很好想吧!但是有些细节和顺序容易搞错。

下面先给出几组数据(不一定完全相同,有spj没关系):

in1:

[]]]]

out1:

[][][][]

in2:

)))(((

out2:

()()()()()()

in3:

“空串”

out3:

“空串”

in4:

([][]([]()))[()]([])

out4:

([][]([]()))[()]([])

code:

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 using namespace std;
 6 const int N=105;
 7 int n,f[N][N]; char a[N]; bool vis[N];
 8 int cmp(int x,int y) {
 9     if (a[x]==(&&a[y]==)) return 1;
10     if (a[x]==[&&a[y]==]) return 1;
11     return 0;
12 }
13 void dfs(int l,int r) {
14     if (l>r) return;
15     if (l==r) {
16         if (vis[l]||vis[r]) return;
17         if (a[l]==() printf("()"); else
18         if (a[l]==)) printf("()"); else
19         if (a[l]==[) printf("[]"); else
20         if (a[l]==]) printf("[]");
21         vis[l]=vis[r]=1;
22         return;
23     }
24     for (int i=l; i<r; i++)
25         if (f[l][i]+f[i+1][r]==f[l][r]) {dfs(l,i),dfs(i+1,r); return;}
26     if (cmp(l,r)) {
27         vis[l]=vis[r]=1;
28         printf("%c",a[l]);
29         dfs(l+1,r-1);
30         printf("%c",a[r]);
31         return;
32     }
33 }
34 int main() {
35     scanf("%s",a+1),n=strlen(a+1);
36     if (n==0) return printf("\n"),0;
37     memset(f,63,sizeof f);
38     for (int i=1; i<=n; i++) f[i][i]=1;
39     for (int i=1; i<n; i++)
40         if (cmp(i,i+1)) f[i][i+1]=0; else f[i][i+1]=2;
41     for (int l=3; l<=n; l++) {
42         for (int i=1; i<=n-l+1; i++) {
43             int j=i+l-1;
44             if (cmp(i,j)) f[i][j]=f[i+1][j-1];
45             for (int k=i; k<j; k++) f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
46         }
47     }
48     dfs(1,n);
49     cout<<endl;
50     return 0;
51 }
View Code

以上是关于[poj P1141] Brackets Sequence的主要内容,如果未能解决你的问题,请参考以下文章

Brackets POJ - 2955 (区间dp)

POJ 2955 - Brackets - [区间DP]

POJ 2955 Brackets

POJ 1141 Brackets Sequence

POJ 2955?Brackets

poj 2955 Brackets