POJ 1141 Brackets Sequence(区间DP, DP打印路径)
Description
We give the following inductive definition of a “regular brackets” sequence:
- the empty sequence is a regular brackets sequence,
- if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences, and
- if a and b are regular brackets sequences, then ab is a regular brackets sequence.
- no other sequence is a regular brackets sequence
For instance, all of the following character sequences are regular brackets sequences:
(), [], (()), ()[], ()[()]
while the following character sequences are not:
(, ], )(, ([)], ([(]
Given a brackets sequence of characters a1a2 … an, your goal is to find the length of the longest regular brackets sequence that is a subsequence of s. That is, you wish to find the largest m such that for indices i1, i2, …, im where 1 ≤ i1 < i2 < … < im ≤ n, ai1ai2… aim is a regular brackets sequence.
Given the initial sequence ([([]])], the longest regular brackets subsequence is [([])].
Input
The input test file will contain multiple test cases. Each input test case consists of a single line containing only the characters (, ), [, and ]; each input test will have length between 1 and 100, inclusive. The end-of-file is marked by a line containing the word “end” and should not be processed.
Output
For each input case, the program should print the length of the longest possible regular brackets subsequence on a single line.
Sample Input
((()))
()()()
([]])
)[)(
([][][)
end
Sample Output
6
6
4
0
6
思路:
1. dp[i][j] 表示 子序列 [i, j] 之间的最小添加括号数
2. dp[i][j] = min(dp[i][k], dp[k+1][j]) k = [i, j]
3. choose[i][j] 表示在 dp[i][j] 中的那个位置切割比较合适, 合适的定义是 dp[i][j] > dp[i][k]+dp[k+1][j]
4. 对 dp[i][j] 的计算, 第一种思路是记忆化搜索, 当时还没考虑到 choose 数组. 对于 choose 数组的求解, 记忆化搜索不能实现. 代码里提供的是基于递推的求解过程, 这种遍历方法我也曾做过, 叫做斜对角线更新, 具体是哪道题目也记不清了, blog 我是有写过的
总结:
1.区间 DP
2. 这个地方 WA 了下, 起初写成 k<=j
for(int k = i; k < j; k++) {
if(dp[i][j] > dp[i][k]+dp[k+1][j]) { // that's why/where need special judge
choose[i][j] = k;
dp[i][j] = dp[i][k]+dp[k+1][j];
}
}
update 2014年3月15日14:43:10
3. 类似的题目有 Leetcode palindrome cut, 并且 palindrome cut 是在原始区间 DP 的基础上加上了一些优化. 矩阵乘法也算是区间 DP
代码:
#include <iostream>
using namespace std; const int INF = 0X3F3F3F3F;
const int MAXN = 110;
int choose[MAXN][MAXN];
int dp[MAXN][MAXN];
char s[MAXN]; void printPath(const int &i, const int &j) {
if(j < i)
return ;
if(i == j) {
if(s[i] == '(' || s[i] == ')') {
cout << "()";
return;
}else if(s[i] == '[' || s[i] == ']') {
cout << "[]";
return;
}
}
if(choose[i][j] == -1) { // 不需要切割
cout << s[i];
printPath(i+1, j-1);
cout << s[j];
}else{
int k = choose[i][j];
printPath(i, k);
printPath(k+1, j);
}
}
int main() {
//freopen("E:\\Copy\\ACM\\测试用例\\in.txt", "r", stdin);
gets(s);
int st = 0, ed = strlen(s);
memset(dp, 0x3F, sizeof(dp));
for(int i = st; i < ed; i ++)
dp[i][i] = 1, dp[i+1][i] = 0;
for(int p = 1; p < ed-st; p ++) {
for(int i = 0, j = i+p; j < ed; i++, j++) {
choose[i][j] = -1;
if((s[i] == '(' && s[j] == ')') || (s[i] == '[' && s[j] == ']')) {
dp[i][j] = min(dp[i][j], dp[i+1][j-1]); // 需要考虑 dp[j][i] = 0
}
for(int k = i; k < j; k++) {
if(dp[i][j] > dp[i][k]+dp[k+1][j]) { // that's why/where need special judge
choose[i][j] = k;
dp[i][j] = dp[i][k]+dp[k+1][j];
}
}
}
}
printPath(0, ed-1);
cout << endl;
return 0;
}
POJ 1141 Brackets Sequence(区间DP, DP打印路径)的更多相关文章
- poj 1141 Brackets Sequence 区间dp,分块记录
Brackets Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 35049 Accepted: 101 ...
- poj 1141 Brackets Sequence (区间dp)
题目链接:http://poj.org/problem?id=1141 题解:求已知子串最短的括号完备的全序列 代码: #include<iostream> #include<cst ...
- poj 1141 Brackets Sequence ( 区间dp+输出方案 )
http://blog.csdn.net/cc_again/article/details/10169643 http://blog.csdn.net/lijiecsu/article/details ...
- 区间DP POJ 1141 Brackets Sequence
Brackets Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29520 Accepted: 840 ...
- POJ 1141 Brackets Sequence (区间DP)
Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a r ...
- POJ 1141 Brackets Sequence
Brackets Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29502 Accepted: 840 ...
- poj 1141 Brackets Sequence(区间DP)
题目:http://poj.org/problem?id=1141 转载:http://blog.csdn.net/lijiecsu/article/details/7589877 定义合法的括号序列 ...
- POJ 1141 Brackets Sequence(DP)
题目链接 很早 很早之前就看过的一题,今天终于A了.状态转移,还算好想,输出路径有些麻烦,搞了一个标记数组的,感觉不大对,一直wa,看到别人有写直接输出的..二了,直接输出就过了.. #include ...
- POJ 1141 Brackets Sequence(括号匹配二)
题目链接:http://poj.org/problem?id=1141 题目大意:给你一串字符串,让你补全括号,要求补得括号最少,并输出补全后的结果. 解题思路: 开始想的是利用相邻子区间,即dp[i ...
随机推荐
- 【Codewars】7×7 摩天大楼
介绍 链接:7×7 Skyscrapers C#答案(原因:懒,但是完全可以转成C++):bajdcc/learnstl 题目(机翻): 在7乘7格的网格中,你只想在每个广场上放置一个摩天大楼,只有一 ...
- git使用教程&&问题列表
git教程[转] http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 git push ...
- js字母大小写字母转换
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD ...
- Makefile学习之路——4
变量的类别有递归扩展变量和简单扩展变量.只用一个“=”符号定义的变量被称为递归扩展变量.通过下面例子观察递归扩展变量的特点. .PHONY: all foo=$(bar) bar=$(ugh) ugh ...
- c#写一个网站后台扫描器
主要分成了那么几个步骤: 1.HTTP状态码 2.字典的导入 3.显示在listview控件当中 第一步: 先来实现HTTP状态码200的判断 try { req = (HttpWebRequest) ...
- loadrunner11 测试restful
loadrunner不知道为啥会有这么大的体积. 一开始用的是c脚本,可是恶心的是又不是完全的c,读文件的fseek居然没有. 后来又折腾java脚本,发现loadrunner11 java要用jdk ...
- Redis简述
Redis 简单介绍 Redis 是全然开源免费的.遵守BSD协议,是一个高性能的key-value数据库. Redis 与其它 key - value 缓存产品有下面三个特点: Redis支持数据的 ...
- Logback手冊 Chapter 1: Introduction
翻译不周,多多包括 ---------------------------------------------------------------------------------------切割线 ...
- USB 转LAN AX88772B 模块驱动添加记录
使用 AX88772B 模块进行扩展百兆网口. 资料地址: http://www.asix.com.tw/cs/products.php?op=pItemdetail&PItemID=105; ...
- FreeMarker 技术资料与问题解决备忘录
技术资料: http://www.ibm.com/developerworks/cn/java/j-lo-freemarker/ FM 解析hash序列 output[name = mouse; pr ...