URAL - 1183 Brackets Sequence 区间dp+记录路径

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 a 1a 2...a n is 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.

Example

input output
([(]
()[()]

思路:dp[i][j]为区间i,到j最少加多少个才能合法,先用区间dp模板把dp[1][n]求出来,但是在求的过程中记录dp[i][j]的决策点

k,dp[i][j]=min(dp[i][k],dp[k+1][j])  在求的时候用一个pos数组记录决策点k,表示在k这个位置分开可以求出i,j区间括号匹配的最小值;当然在str[i]与str[j]匹配的时候 dp[i][j]=dp[i+1][j-1];

那么怎么打印呢,递归打印  print(1,n)

当 l>r 不合法,

l==r 如果str[l]为(,)直接输出()其他输出[],

如果 l<r  

       如果pos[l][r]==-1 表示没有找到中断点,那么str[l]是 和str[r]匹配的,

      else 那就递归 print(l,pos[l][r]),print(pos[l][r]+1,r)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstdlib>
#include<deque> 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<double,double>P;
const int len=1e2+5;
const double pi=acos(-1.0);
const ll mod=1e8+7;
int dp[len][len];
int pos[len][len];
int n;
char str[len];
void print(int l,int r) 
{
	if(l>r)return ;
	if(l==r)
	{
		if(str[l]=='('||str[l]==')')printf("()");
		else printf("[]");
	}
	else 
	{
		if(pos[l][r]==-1)
		{
			putchar(str[l]);
			print(l+1,r-1);
			putchar(str[r]);
		}
		else
		{
			print(l,pos[l][r]);
			print(pos[l][r]+1,r);
		}
	}
}
int main()
{
	while(~scanf("%s",str+1)) 
	{
		n=strlen(str+1);
		memset(dp,0x3f,sizeof(dp));
		memset(pos,-1,sizeof(pos));
		for(int i=1;i<=n;++i)dp[i][i]=1,dp[i][i-1]=0;
		for(int le=2;le<=n;++le)
		{
			for(int i=1;i+le-1<=n;++i)
			{
				int j=i+le-1;
				if(str[i]=='('&&str[j]==')'||str[i]=='['&&str[j]==']')dp[i][j]=min(dp[i+1][j-1],dp[i][j]);
				for(int k=i;k<j;++k)
				{
					if(dp[i][j]>dp[i][k]+dp[k+1][j])
					{
						pos[i][j]=k;
						dp[i][j]=dp[i][k]+dp[k+1][j];
					}
				}
			}
		}
		print(1,n);
		puts("");
	}
}


 

猜你喜欢

转载自blog.csdn.net/hutwuguangrong/article/details/88409119