poj 1141

给一个括号序列,可以加括号,求使得其合法的最短的括号序列。
和poj 2955 相似,都是有关合法括号序列,还是区间dp,d[i][j] 表示使得[i,j]合法的最小花费。
然后还要打印处理后的括号序列,递归打印即可。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

char s[110];
int d[110][110],len;

int match(int i,int j){
	return (s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']');
}
int dp(int i,int j){
	int & ans = d[i][j];
	if(ans != 1e9) return ans;
	if(i == j )return ans = 1;
	if(i > j) return ans = 0;
	if(match(i,j)) ans = min(ans,dp(i+1,j-1));
	for(int k = i;k<j;k++) ans = min(ans,dp(i,k)+dp(k+1,j));
	return ans;
} 

void print(int i,int j){
	if(i>j) return ;
	if(i == j){
		if(s[i]=='(' || s[i] ==')') printf("()");
		else printf("[]");
		return ; 
	}
	if(match(i,j) && d[i][j] == d[i+1][j-1]) {
		printf("%c",s[i]);
		print(i+1,j-1);
		printf("%c",s[j]);
		return ;
	}
	for(int k = i;k<j;k++){
		if(d[i][j] == d[i][k] + d[k+1][j]){
			print(i,k);
			print(k+1,j);
			return ;
		}
	}
}

int main(){
	while(gets(s)){ 
		len = strlen(s);
		for(int i = 0;i<len;i++) for(int j = 0;j<len;j++) d[i][j] = 1e9;
		dp(0,len-1);
		print(0,len-1); 
		printf("\n");
	} 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/winhcc/article/details/89055783
今日推荐