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 ...
随机推荐
- python文件和目录操作方法大全
一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法. 1.得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()2.返回指定目录下的所有文件和 ...
- jsp报源码
刚在get的一个姿势.在参数后面加负号即爆出源码. w7oami 表哥解释道其原理如下: 1.用了@file_get_contents 函数 2.cdn 或者负载均衡 才导致爆出源码.
- size_t ssize_t socklen_t
size_t 解释一:为了增强程序的可移植性,便有了size_t,它是为了方便系统之间的移植而定义的,不同的系统上,定义size_t可能不一样. 在32位系统上 定义为 unsigned int 也就 ...
- Java学习理解路线图
信息来自知乎网友 学习截图:来自开源力量
- Lua中的loadfile、dofile、require详解
1.loadfile——只编译,不运行 loadfile故名思议,它只会加载文件,编译代码,不会运行文件里的代码.比如,我们有一个hellofile.lua文件: 复制代码代码如下: print(“h ...
- The declared package "com.dao" does not match the expected package "src.com.dao"
今天把项目代码上传到svn后出现例如以下错误:The declared package "com.dao" does not match the expected package ...
- mongodb查询之从多种分类中获取各分类最新一条记录
mongodb查询之从多种分类中获取各分类最新一条记录 2017年04月06日 13:02:47 monkey_four 阅读数:6707更多 个人分类: MongoDBJavaScript 文章 ...
- PHPstorm8 自动换行设置方法
PHPstorm是一款非常不错的PHP开发工具,有很多需要自己设置.比如,IDE常见的代码自动换行功能需要我们自己去配置才能实现. File -> Settings -> Editor ...
- 上手并过渡到PHP7(2)——必须传递int, string, bool参数?没问题
Type hints, Type safe 泊学实操视频 泊学原文链接PHP 7中最引人注目的新特性之一,无疑是Scalar type hints.我们可以在函数参数和返回值中使用scalar typ ...
- Quill + Framework 7 移动端无法获取焦点
Quill 是一个轻量级的富文本编辑器.最近公司项目中需要用到这个东东.使用方法可以直接查看它的官网地址或者Github地址: Github地址:quilljs 官网地址:quill官网 主要说一下用 ...