括号序列(uva 1626)
2018-03-29 17:30
393 查看
题目链接 https://cn.vjudge.net/problem/UVA-1626
【题意】
定义如下正规括号序列
空序列是正规括号序列
如果S是正规括号序列,那么[S], (S)也是正规括号序列
如果A和B都是正规括号序列,那么AB也是正规括号序列
输入一个长度不超过100的只有’(‘, ‘)’, ‘[‘, ‘]’组成的字符串序列,添加最少的括号得到一个规则序列,如果有多解输出任意一组即可
【思路】
设将串S变为正规序列至少需要dp(S)个括号,那么
如果S的结构是(S’)或[S’],那么就可以转移到dp(S’)
如果S至少有两个字符,那么可以划分为两个部分AB,转移到dp(A)+dp(B)
编程实现的时候,dp(i,j)表示的是把s[i~j]变成正规括号序列所需要添加的最少括号个数,状态转移方程为dp(i,j)=min{ dp(i+1,j-1), s[i]和s[j]匹配
dp(i,k)+dp(k+1,j),i<=k< j }
打印解的时候用递归函数打印,我感觉这个思路很巧妙,自己很难想到,基本上是把紫书的代码抄了一遍,然后下面的代码用C++11能过,用C++会编译错误,会在gets()这里报错,然而并不知道这是为什么
【题意】
定义如下正规括号序列
空序列是正规括号序列
如果S是正规括号序列,那么[S], (S)也是正规括号序列
如果A和B都是正规括号序列,那么AB也是正规括号序列
输入一个长度不超过100的只有’(‘, ‘)’, ‘[‘, ‘]’组成的字符串序列,添加最少的括号得到一个规则序列,如果有多解输出任意一组即可
【思路】
设将串S变为正规序列至少需要dp(S)个括号,那么
如果S的结构是(S’)或[S’],那么就可以转移到dp(S’)
如果S至少有两个字符,那么可以划分为两个部分AB,转移到dp(A)+dp(B)
编程实现的时候,dp(i,j)表示的是把s[i~j]变成正规括号序列所需要添加的最少括号个数,状态转移方程为dp(i,j)=min{ dp(i+1,j-1), s[i]和s[j]匹配
dp(i,k)+dp(k+1,j),i<=k< j }
打印解的时候用递归函数打印,我感觉这个思路很巧妙,自己很难想到,基本上是把紫书的代码抄了一遍,然后下面的代码用C++11能过,用C++会编译错误,会在gets()这里报错,然而并不知道这是为什么
#include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; const int inf=2e9; const int maxn=105; char s[maxn]; int dp[maxn][maxn]; bool match(char c1,char c2){ if(c1=='(' && c2==')') return true; if(c1=='[' && c2==']') return true; return false; } void print(int i,int j){//打印s[i~j]的解 if(i>j) return; if(i==j){ if(s[i]=='(' || s[i]==')') printf("()"); else printf("[]"); return; } int ans=dp[i][j]; if(match(s[i],s[j]) && ans==dp[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(ans==dp[i][k]+dp[k+1][j]) { print(i,k); print(k+1,j); return; } } } int main(){ int t; scanf("%d",&t); getchar(); while(t--){ getchar(); gets(s); int len=strlen(s); memset(dp,0,sizeof(dp)); for(int i=0;i<len;++i) dp[i][i]=1; for(int L=1;L<len;++L){ for(int i=0;i+L<len;++i){ int j=i+L; dp[i][j]=inf; if(match(s[i],s[j])) dp[i][j]=min(dp[i][j],dp[i+1][j-1]); for(int k=i;k<j;++k) dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); } } print(0,len-1); printf("\n"); if(t) printf("\n"); } return 0; }
相关文章推荐
- (mark)UVA-1626 括号序列,转移方程很有意思
- UVa 1626 括号序列——区间DP
- UVa 1626 括号序列(矩阵连乘)
- [UVa1626]括号序列
- UVA 1626 括号序列
- 例题9-10 括号序列 UVa1626
- UVA 1626 括号序列(区间dp)
- Uva 1626,括号序列
- uva 1626 括号序列
- dp uva1626 括号序列
- uva1626 括号序列
- 区间DP(括号序列,uva1626)
- NYOJ15 - UVA1626 括号匹配问题(dp)
- UVA 1626 Brackets sequence(括号匹配 + 区间DP)
- uva 1626 添加最少的括号使得括号匹配
- UVA1626 Bracketssequence(括号匹配)
- NYOJ15 - UVA1626 括号匹配问题(区间dp)
- ***UVa-1626 Brackets sequence ACM解题报告(巧妙地递推+打印)经典的括号 dp题
- uva 1626(动态规划起步第五天 LIS变形 括号匹配)
- Parenthesis UVALive - 4882 删除不必要的括号序列,模拟题 + 数据