poj 1141 括号匹配

根据“黑书”的思路,定义:

d[i][j]为输入序列从下标i到下标j最少需要加多少括号才能成为合法序列。0<=i<=j<len
(len为输入序列的长度)。

c[i][j]为输入序列从下标i到下标j的断开位置,如果没有断开则为-1。

当i==j时,d[i][j]为1

当s[i]==‘(‘ && s[j]==‘)‘ 或者 s[i]==‘[‘ && s[j]==‘]‘时,d[i][j]=d[i+1][j-1]

否则d[i][j]=min{d[i][k]+d[k+1][j]} i<=k<j ,  c[i][j]记录断开的位置k

采用递推方式计算d[i][j]

输出结果时采用递归方式输出print(0, len-1)

输出函数定义为print(int i, int j),表示输出从下标i到下标j的合法序列

当i>j时,直接返回,不需要输出

当i==j时,d[i][j]为1,至少要加一个括号,如果s[i]为‘(‘
或者‘)‘,输出"()",否则输出"[]"

当i>j时,如果c[i][j]>=0,说明从i到j断开了,则递归调用print(i,
c[i][j]);和print(c[i][j]+1, j);

如果c[i][j]<0,说明没有断开,如果s[i]==‘(‘ 则输出‘(‘、 print(i+1, j-1); 和")"

否则输出"[" print(i+1, j-1);和"]"

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

using namespace std;
int dp[100][100];
int c[100][100]={-1};
int len;
char s[1000];

void cal(){
	for(int i=0;i<len;i++) dp[i][i]=1;
	int k,l;
    for(int i=1;i<len;i++)
		for(int j=0;j+i<len;j++){
			l=j+i;
			int minn=dp[j][j]+dp[j+1][l];
			c[j][l]=j;
			for(int k=j+1;k<l;k++){
				if(dp[j][k]+dp[k+1][l]<minn){
					minn=dp[j][k]+dp[k+1][l];
				    c[j][l]=k;
				}
			}
			dp[j][l]=minn;
			if(s[j]=='('&&s[l]==')'||s[j]=='['&&s[l]==']'){
				if(dp[j+1][l-1]<minn){
					dp[j][l]=dp[j+1][l-1];
					c[j][l]=-1;
				}
			}

		}
}

void print(int i,int j){
	if(i>j)return ;
	if(i==j){
		if(s[i]=='('||s[j]==')')
		cout<<"()";
		else
		cout<<"[]";
	}
	if(i<j){
		if(c[i][j]>=0){
			print(i,c[i][j]);
			print(c[i][j]+1,j);
		}
		else {
			if(s[i]=='('){
				cout<<"(";
				print(i+1,j-1);
				cout<<")";
			}
			else if(s[i]=='['){
				cout<<"[";
				print(i+1,j-1);
				cout<<"]";
			}
		}
	}
}

int main(){
	cin>>s;
	len=strlen(s);
	cal();
	print(0,len-1);
	puts("");
}
时间: 2024-11-05 06:13:27

poj 1141 括号匹配的相关文章

POJ 2955 Brackets (区间dp 括号匹配)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3951   Accepted: 2078 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg

POJ 1141-Brackets Sequence(区间dp括号匹配打印路径)

题目地址:POJ 1141 题意:给出一串由'(')'' [ ' ' ] '组成的串,将给出的括号序列以添加最小数目括号的形式进行配对. 思路:dp[i][j]表示当前子序列需要添加的最小字符数,path存储的是所有子问题的解.然后详情看代码解释. #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #in

POJ C程序设计进阶 编程题#4:括号匹配问题

编程题#4:扩号匹配问题 来源: POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 在某个字符串(长度不超过100)中有左括号.右括号和大小写字母:规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配.写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号.不能匹配的左括号用"$"标注,不能匹配的右括号用&quo

poj 2955 Brackets 括号匹配 区间dp

题意:最多有多少括号匹配 思路:区间dp,模板dp,区间合并. 对于a[j]来说: 刚開始的时候,转移方程为dp[i][j]=max(dp[i][j-1],dp[i][k-1]+dp[k][j-1]+2), a[k]与a[j] 匹配,结果一组数据出错 ([]]) 检查的时候发现dp[2][3]==2,对,dp[2][4]=4,错了,简单模拟了一下发现,dp[2][4]=dp[2][1]+dp[2][3]+2==4,错了 此时2与4已经匹配,2与3已经无法再匹配. 故转移方程改为dp[i][j]=

uva1626 poj 1141 Brackets Sequence 区间dp 打印路径

// poj 1141 Brackets Sequence // 也是在紫书上看的一题,uva就是多了一个t组数据. // 经典区间dp // dp(i,j)表示区间[i,j]内所需要增加的括号数目 // 则分为两种情况 // 一种是s[i]和s[j]是匹配的则 // dp[i][j] = min(dp[i][j],dp[i+1][j-1]) // 另外一种情况是不匹配 // dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]){i<k<j}; // 但是无

水了两道括号匹配

POJ 1141 给一段括号序列,要求增加最少的括号,使之合法,输出序列. dp[i][j]表示使给定序列的i到j成为合法序列所需添加的最少括号数,dp[0][length-1]即是答案,转移的话,如果s[i]和s[j]可以匹配那么dp[i][j] = dp[i+1][j-1],否则就考虑在中间选择一个位置m,使分割成的两个序列各自成为合法序列.方案的话就是多开一个数组记录然后递归输出.状态是从长度小的序列转移到长度长的序列,所以两层循环,外层枚举长度,内层枚举头位置即可.写成记忆化搜索简单一点

[ACM] POJ 1141 Brackets Sequence (区间动态规划)

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

Brackets Sequence POJ - 1141 (区间dp)

Brackets Sequence POJ - 1141 题意:给一个括号序列,问最少添加多少个括号似的原序列匹配,并输出新序列. 用dp[i][j]表示i到j最少添加几个括号,flag[i][j]表示i和j之间需要添加括号的位置. 1 #include<cstdio> 2 #include<algorithm> 3 #include<string> 4 #include<iostream> 5 #include <cstdlib> 6 #inc

POJ 1141 Brackets Sequence (区间dp 记录路径)

题目大意: 给出一种不合法的括号序列,要求构造出一种合法的序列,使得填充的括号最少. 思路分析: 如果只要求输出最少的匹配括号的数量,那么就是简单的区间dp dp[i][j]表示 i - j 之间已经合法了最少添加的括号数. 转移 就是 dp[i] [j] = min  (dp[i+1][j]+1 , dp[ i+ 1] [ k -1 ] + dp[k+1] [j] (i k 位置的括号匹配)) 其次我们要记录路径,你发现  如果 dp [i] [j] 是由 dp [i+1] [j] 转移过来的