#UVA1626#Brackets sequence(括号序列---石子归并类Dp)
来源:互联网 发布:网络暴力相关事件 编辑:程序博客网 时间:2024/06/06 00:54
题意:
给出T个字符串,仅由 '(' ')' '[' ']' 四种 字符组成,其中 ’()‘ '[]'为合法,'()[]' '([])' '[()]' 均为合法,而’[(])‘ '[)' 则为不合法状态
求最少添加多少个字符,使得字符串合法,输出合法的其中一种方案。(原始字符串字符不多于100个)
第一行为字符串数量。
样例输入:
1
([(]
样例输出:
()[()]
这题让人很容易想起之前做过的一道叫“剔除多余括号”的分治题,
当时是看外围那一圈是否可以去掉,
然后这题我就想分成两种情况,
第一,如果外围匹配,那么递归到里面
第二,长度大于一,无论是否匹配,都枚举中间分界点k,将字符串分为两段,分别递归求解
边界条件是长度为空时返回,为1时判断后匹配返回,用的是string类型,比较方便。
其实这个想法就像搜索一样,去把所有的方案都试过了,很显然会TLE,事实上也的确如此。
正解Dp:
令Dp[ i ][ j ]表示从 i 到 j 的字符串中需要添加括号的数量,
对于S[i]是否等于S[j],会产生同上分析的两种情况。
Dp[ i ][ j ] = min(Dp[ i ][ k ] + Dp[ k + 1 ][ j ]);
当S[i] == S[j]时,有Dp[ i ][ j ] = min(Dp[ i + 1 ][ j - 1 ], Dp[ i ][ j ]);
输出的时候同样分类讨论,根据Dp[ i ][ j ]中的值辅助输出结果,代码还是非常好懂的。
先给出TLE代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<map>using namespace std;string X;string Table[4] = {"(", ")", "[", "]"};map<string, string>MAP;string Work(string S){ if(MAP.count(S))return MAP[S]; if(S.size() == 0) return string(""); if(S.size() == 1){ if(S == Table[0]) return S + Table[1]; else if(S == Table[1]) return Table[0] + S; else if(S == Table[2]) return S + Table[3]; else return Table[2] + S; } int len = S.size(); string rt, p; if((S[0] == '[' && S[len - 1] == ']') || (S[0] == '(' && S[len - 1] == ')')) rt = S[0] + Work(S.substr(1, len - 2)) + S[len - 1]; if(len >= 2) for(int i = 1; i < len; ++ i){//S = ")(" string lsub = S.substr(0, i); string l = Work(lsub);//"()" if(MAP.count(lsub) == 0) MAP[lsub] = l; string rsub = S.substr(i, len - i); string r = Work(rsub);//"()" if(MAP.count(rsub) == 0) MAP[rsub] = r; p = l + r;//"()()" if(p.size() < rt.size() || rt.size() == 0) rt = p; } return rt;}int main(){ int T; scanf("%d", &T); while(T --){ cin >> X; string rt = Work(X); cout << rt << endl; } return 0;}
正解
Code:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<algorithm>using namespace std;const int Max = 100;const int INF = 0x3f3f3f3f;int N;char S[Max + 5];int Dp[Max + 5][Max + 5];bool Match(int a, int b){ if((S[a] == '(' && S[b] == ')') || (S[a] == '[' && S[b] == ']')) return 1; return 0;}void Print(int l, int r){ if(l > r) return ; if(l == r){ if(S[l] == '(' || S[l] == ')') printf("()"); else printf("[]"); return ; } if(Match(l, r) && Dp[l][r] == Dp[l + 1][r - 1]){ printf("%c", S[l]); Print(l + 1, r - 1); printf("%c", S[r]); return ; } for(int k = l; k < r; ++ k) if(Dp[l][r] == Dp[l][k] + Dp[k + 1][r]){ Print(l, k); Print(k + 1, r); return ; }}int main(){ int T, flg = 0; scanf("%d", &T); getchar(); while(T --){ gets(S); gets(S); N = strlen(S); if(! N){ if(flg ++) putchar(10); putchar(10); continue; } for(int i = 0; i < N; ++ i) Dp[i][i] = 1; for(int i = N - 1; i >= 0; -- i){ for(int j = i + 1; j < N; ++ j){ Dp[i][j] = INF; if(Match(i, 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]); } } if(flg ++) putchar(10); Print(0, N - 1); putchar(10); } return 0;}
阅读全文
0 0
- #UVA1626#Brackets sequence(括号序列---石子归并类Dp)
- UVA1626 - Brackets sequence(区间DP--括号匹配+递归打印)
- [UVA1626]Brackets sequence(dp)
- dp uva1626 括号序列
- 区间DP(括号序列,uva1626)
- UVA1626 / ZOJ1463 Brackets sequence 区间DP
- uva1626 Brackets sequence
- UVa1626 Brackets sequence
- UVA1626 - Brackets sequence
- UVA1626 Brackets sequence
- UVa1626 Brackets sequence
- poj1141 Brackets Sequence 括号序列
- uva1626 poj 1141 Brackets Sequence 区间dp 打印路径
- 例题9-10 UVa1626&&POJ1141 Brackets Sequence(DP)
- uva1626 括号序列
- [UVa1626]括号序列
- 区间dp模型(石子归并,括号匹配,整数划分)
- 区间dp模型(石子归并,括号匹配,整数划分)
- live555搭建简易流媒体服务
- java内存回收机制相关
- 扑克牌与一副扑克牌
- (Swift) iOS Apps with REST APIs(六) -- 使用PINRemoteImage实现图片加载及缓存
- Unity3D学习记录——对同标签物体操作
- #UVA1626#Brackets sequence(括号序列---石子归并类Dp)
- x264源代码简单分析:宏块编码(Encode)部分
- 期望为线性时间的选择算法
- Java Client API for RabbitMQ
- 大数据表转移hdfs后查询处理
- 堆栈
- 响应式布局-----媒体查询
- 关于position:relative,absolute,fixed和static
- x264源代码简单分析:熵编码(Entropy Encoding)部分