您的位置:首页 > 产品设计 > UI/UE

poj1141 Brackets Sequence 区间dp

2014-07-31 11:06 260 查看
Brackets Sequence

Time Limit: 1000MS Memory Limit: 65536KB64bit IO Format: %I64d & %I64u

[Submit] [Go Back] [Status]

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[i][j] 代表i到j的最小的合法匹配 pre[i][j] 代表i到j区间中的最小合法状态的中间的k

因为区间枚举时 dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j])所以把断点记录下来分段输出最后的答案。

其中边界是i == j dp[i][j] = 1. i > j dp[i][j] = 0;

代码

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char a[150];
int dp[120][120],pre[120][120],n;
int print(int x, int y)
{
if(x > y)
return 1;
if(x == y)
{
if(a[x] == '('||a[x] == ')')
cout<<"()";
else
cout<<"[]";
}
else if(pre[x][y] == 0)
{
if(a[x] == '(')
cout<<"(";
else
cout<<"[";
print(x+1,y-1);
if(a[y] == ')')
cout<<")";
else
cout<<"]";
}
else
{
print(x, pre[x][y]);
print(pre[x][y]+1, y);
}
}
void ff()
{
int i,j,k,l;
for(i =0;i<120;i++)
{
for(j = 0; j < 120;j++)
{
if(j < i)
dp[i][j] = 0;
else if(i == j)
dp[i][j] = 1;
else
dp[i][j] = 1000;
pre[i][j] = -1;
}
}
for(l = 1; l < n;l++)
{
for(i = 1; i <= n - l;i++)
{
j = i + l;
if(a[i] == '('&&a[j] ==')'||a[i] =='['&&a[j] ==']')
{
dp[i][j] = dp[i+1][j-1];
pre[i][j] = 0;
}                                       //由于当两边合法的时候不一定是最短的 所以还是要继续区间dp判断是否有更小值
for( k = i; k < j;k++)
{
int vis = dp[i][k] + dp[k+1][j];
if(vis < dp[i][j])
{
dp[i][j] = vis;
pre[i][j] = k;
}
}
}
}
print(1,n);
cout<<endl;

}
int main()
{
while (gets(a+1))
{
n = strlen(a+1);
ff();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: