poj1141 2010.2.22

本文探讨了如何找出包含特定括号序列的最短有效括号序列。通过动态规划算法,实现了对输入括号序列的有效处理,并提供了一个示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

poj1141 2010.2.22

Brackets Sequence

Time Limit: 1000MS  Memory Limit: 65536K

Total Submissions: 10822  Accepted: 2877  Special Judge

 

Description

 

Let us define a regular brackets sequencein 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, thenAB is a regular sequence.

 

For example, all of the following sequencesof characters are regular brackets sequences:

 

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

 

And all of the following charactersequences are not:

 

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

 

Some sequence of characters '(', ')', '[',and ']' is given. You are to find the shortest possible regular bracketssequence, that contains the given character sequence as a subsequence. Here, astring a1 a2 ... an is called a subsequence of the string b1 b2 ... bm, ifthere exist such indices 1 = i1 < i2 < ... < in = m, that aj = bij forall 1 = j = n.

Input

 

The input file contains at most 100brackets (characters '(', ')', '[' and ']') that are situated on a single linewithout any other characters among them.

Output

 

Write to the output file a single line thatcontains some regular brackets sequence that has the minimal possible lengthand contains the given sequence as a subsequence.

Sample Input

 

([(]

Sample Output

 

()[()]

Source

 

Northeastern Europe 2001

黑书上有


#include <stdio.h>
#include <string.h>

#define MAXN 100+10
#define INF 999999999

char s[MAXN];
int dp[MAXN][MAXN],path[MAXN][MAXN];

void output(int,int);

void output(int i,int j)
{
	if (i>j)
		return;
	if (i==j)
	{
		if (s[i]=='('||s[j]==')')
			printf("()");
		else
			printf("[]");
	}
	else
		if (path[i][j]==-1)
		{
			printf("%c",s[i]);
			output(i+1,j-1);
			printf("%c",s[j]);
		}
		else
		{
			output(i,path[i][j]);
			output(path[i][j]+1,j);
		}
}


void main()
{
	scanf("%s",s);
	memset(dp,0,sizeof(dp));
	int n=strlen(s);
	for(int i=0;i<n;++i)
		dp[i][i]=1;
	for(int p=1;p<n;++p)
		for(int i=0;i<n-p;++i)
		{
			int j=i+p;
			dp[i][j]=INF;
			if ((s[i] == '(' && s[j] == ')') || (s[i] == '[' && s[j] == ']'))
				if(dp[i][j]>dp[i+1][j-1])
					dp[i][j]=dp[i+1][j-1],path[i][j]=-1;
				for (int k = i; k < j; ++k)
				{
					if (dp[i][j] > dp[i][k] + dp[k+1][j])
					{
						dp[i][j] = dp[i][k] + dp[k+1][j];
						path[i][j] = k;
					}
				}
		}
		output(0,n-1);
		printf("\n");

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值