POJ 1141-Brackets Sequence(区间DP)

题目链接:

http://poj.org/problem?id=1141

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

()[()]

//区间DP
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define maxn 1005
#define inf 0x3f3f3f3f
using namespace std;
char s[maxn];
int dp[maxn][maxn];             //dp[i][j]表示区间i~j内需要最少的字符数能够匹配
int path[maxn][maxn];           //path[i][j]是表示怎么达到dp[i][j]状态的

int peidui(char c1, char c2)
{
	if((c1=='(' && c2==')')||(c1=='['&&c2==']'))
		return 1;
	return 0;
}

//输出区间(x,y)的配对结果
void print_path(int x, int y)
{
    if(x>y)
        return;
	//只剩下一个,补上完整的
	if(x==y)
	{
		if(s[x]=='(' || s[x]==')')
			printf("()");
		else
			printf("[]");
		return;
	}
	if(path[x][y]==-1)   //s[x]和s[y]配对
	{
		printf("%c", s[x]);
		print_path(x+1, y-1);
		printf("%c", s[y]);
	}
	else
	{
		int k = path[x][y];
		print_path(x, k);
		print_path(k+1, y);
	}
}

int main()
{
	while(gets(s))
	{
		memset(dp, 0, sizeof(dp));
		int l = strlen(s);
		for(int i=0; i<l; i++)       //单个字符需要1个
			dp[i][i] = 1;
		for(int len=1; len<l; len++)
			for(int i=0; i<l-len; i++)
			{
			    int j = i+len;
				dp[i][j] = inf;
				if(peidui(s[i], s[j]))
				{
					if(dp[i+1][j-1]<dp[i][j])
						{
							dp[i][j] = dp[i+1][j-1];
							path[i][j] = -1;
						}
				}

                for(int k=i; k<j; k++)
                {
                    if(dp[i][k]+dp[k+1][j] < dp[i][j])
                    {
                        dp[i][j] = dp[i][k]+dp[k+1][j];
                        path[i][j] = k;
                    }
                }
			}
		print_path(0, l-1);
		printf("\n");
	}
	return 0;
}



猜你喜欢

转载自blog.csdn.net/qq_31281327/article/details/76358705