poj 1141 Brackets Sequence(逆序DP)

本文介绍了使用动态规划解决算法艺术与信息学竞赛中关于匹配完全数量的问题,通过实例和代码解释了求解过程。

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

《算法艺术与信息学竞赛》 P113~P115,注释掉的内容可以求得最少匹配完全数量。

path 表示的是在某个中间序列得到了较小的路径序号。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAX_N 105
#define MAX 1<<20
#define min(a,b) (a)<(b)?(a):(b)
char str[MAX_N];
int dp[MAX_N][MAX_N],len,path[MAX_N][MAX_N];
void init(){
    len=strlen(str+1);
    memset(dp,0,sizeof(dp));
    memset(path,0,sizeof(path));
    for(int i=0;i<=len;i++)
	dp[i][i]=1; 
}
void MinMatch(){
    for(int p=1;p<=len-1;p++){
	for(int i=1;i<=len-p;i++){
	    int j=i+p;
	    dp[i][j]=1<<20;
		for(int q=i;q<=j;q++)
	    if((str[i]=='('&& str[j]==')') 
		|| (str[i] =='[' && str[j] == ']') ){
		if(dp[i][j]>dp[i+1][j-1])
		    dp[i][j]=dp[i+1][j-1];
		// dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
	    }
/*	    if(str[i] =='(' || str[i] == '['){
		dp[i][j]=min(dp[i][j],dp[i+1][j])+1;
	    }
	    if(str[j] == ')' || str[j] == ']'){
		dp[i][j]=min(dp[i][j],dp[i][j-1])+1;
	    }
*/
	    for(int k=i;k<j;k++){
		//dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]);
		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;
	    }
	}
    }

}
void Output(int i,int j){
    if(i>j) return ;
    if(i==j){
	if(str[i]=='(' || str[i] ==')') 
	    cout<<"()";
	else
	    cout<<"[]";
    }
    else if(!path[i][j]){
	cout<<str[i];
	Output(i+1,j-1);
	cout<<str[j];
    }
    else
	Output(i,path[i][j]),Output(path[i][j]+1,j);
}
	
int main(){
    
    while(gets(str+1)){
	init();
	if(len==0){
	cout<<endl;
	continue;
	} 
	MinMatch();
	Output(1,len);
	cout<<endl;
    }
    return 0;
}
	


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值