POJ1141括号序列 区间dp求调
  • 板块学术版
  • 楼主HeiCat0725
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/10/4 08:44
  • 上次更新2024/10/4 10:33:37
查看原帖
POJ1141括号序列 区间dp求调
941560
HeiCat0725楼主2024/10/4 08:44

题目链接。

题目大意:给定一个只含有括号'(' ')' '[' ']'的长度在100以内的字符串,输出以这个字符串为子序列的最短合法括号串。相似题目(我没有UVA账号)

学校oj上通过(但是老师造的数据很水qwq)POJ不过,没调出来。

#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;

string s;
int n;
int dp[105][105],num[105][105];//断点记录
void dfs(int l,int r){
	if(l==r){
		if(s[l-1]=='('||s[l-1]==')'){
			cout<<"()";
		}else{
			cout<<"[]";
		}
		return ;
	}else if(l>r){
		return ;
	}else{
		if(num[l][r]==0){
			cout<<s[l-1];
			dfs(l+1,r-1);
			cout<<s[r-1];
		}else{
			dfs(l,num[l][r]);
			dfs(num[l][r]+1,r);
		}
	}
}
int main(){
	cin>>s;
	n=s.size();
	memset(dp,0x3f,sizeof(dp));
	for(int i=1;i<=n;i++) dp[i][i]=1;
	for(int i=1;i<n;i++){
		if((s[i-1]=='('&&s[i]==')')||(s[i-1]=='['&&s[i]==']')){
			dp[i][i+1]=0;
			num[i][i+1]=0;
		}else{
			dp[i][i+1]=2;
			num[i][i+1]=i;
		}
	}
	for(int k=3;k<=n;k++){
		for(int i=1;i<=n-k+1;i++){
			int j=i+k-1;
			if((s[i-1]=='['&&s[j-1]==']')||(s[i-1]=='('&&s[j-1]==')')) dp[i][j]=dp[i+1][j-1],num[i][j]=0;
			for(int w=i;w<j;w++){
				if(dp[i][j]>=dp[i][w]+dp[w+1][j]){
					dp[i][j]=dp[i][w]+dp[w+1][j];
					num[i][j]=w;
				}
			}
		}
	}
	//cout<<s.size()+dp[1][n];
	dfs(1,n);
	return 0;
}
/*

*/

2024/10/4 08:44
加载中...