Brackets Sequence
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 23551   Accepted: 6647   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

()[()]
  
首先说,我对输方案目前阶段还有阴影,所以纠缠这道题很久……
不过仔细分析其实多简单的。
首先,分析如果不让输方案而是输添加括号的个数该怎么办:(觉得这个问题很弱的可以直接跳到空行的后面……顺便orz)
典型区间dp
f[i][j]表示区间i到j的串合法要添加的括号数
那么 转移方程:
    1.如果c[i]和c[j]恰好是一对括号,那么: f[i][j] =min(f[i][j] , f[i + 1][j - 1])
    2.否则  f[i][j] = min(f[i][j] ,f[i][k] + f[k + 1][j];
然后是要注意边界—— i==j 时 f[i][j] = 1;
  
  
接下来终于该考虑输出方案的问题了:
显而易见,只有我们知道了f[i][j]是从那里转移过来的我们就知道怎么加括号了(用g[i][j]记录)
如果是从第一种情况转移来那么应该是输出 :‘(’ + [i+1]到[j-1]的情况 + ‘)’
如果是从第二种情况转移来那么应该是输出 :i 到 g[i][j] 的情况 链接上 g[i][j]+1到r的情况
这个显而易见是用递归很好实现的
 
注意poj的读入有空行,所以用gets读入
还要特判读入的是不是空字符串哦!!! 

#include <iostream>
#include <cstring>
#include <string.h>
#include <cstdio>
using namespace std;
const long N = 120;
char c[120];
long f[120][120];
long g[120][120];
long n;
void prt(long l, long r)
{
	if (r == l)
	{
		if ((c[l] == '(') || (c[l] == ')')) printf("()");
		if ((c[l] == '[') || (c[l] == ']')) printf("[]");
		return ;
	}
 	if (g[l][r] == -1)
	{
		if ( (c[l] == '(') && (c[r] == ')') )
		{
			printf("(");
			prt(l + 1, r - 1);
			printf(")");
		}
		if ( (c[l] == '[') && (c[r] == ']') )
		{
			printf("[");
			prt(l + 1, r - 1);
			printf("]");
		}
	}
	else{
		prt(l, g[l][r]);
		prt(g[l][r] + 1, r);
	}

}
void dp()
{
	n = strlen(c);
	memset(f, 127, sizeof(f));
	memset(g, -1, sizeof(g));
	for (long i = 0; i < n; i++)
	{
		f[i][i] = 1;
	}
	for (long l = 2; l <= n; l++)
	{
		for (long i =0; i + l - 1 < n; i++)
		{
			long j = i + l - 1;

			if (((c[i] == '[') && (c[j] == ']')) || ((c[i] == '(') && (c[j] == ')')))
			{
				if (i + 1 == j) f[i][j] =0;
				if (f[i][j] > f[i + 1][j - 1])
				{
					f[i][j] = f[i + 1][j - 1];
				}
			}

			for (long k = i; k < j; k++)
			{
				if (f[i][j] > f[i][k] + f[k + 1][j])
				{
					f[i][j] = f[i][k] + f[k + 1][j];
					g[i][j] = k;
				}
			}
		}
	}
	//cout << f[0][n - 1] << endl;
}
int main()
{
	freopen("poj1141.in", "r", stdin);
	while (gets(c))
	{
	    if (strlen(c) == 0)
	    {
			printf("\n");
			continue;
	    }
		dp();
		prt(0, n - 1);
		printf("\n");
	}
    return 0;
}