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 i1i2, …, im where 1 ≤ i1 < i2 < … < im ≤ nai1ai2… 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打印路径)的更多相关文章

  1. poj 1141 Brackets Sequence 区间dp,分块记录

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 35049   Accepted: 101 ...

  2. poj 1141 Brackets Sequence (区间dp)

    题目链接:http://poj.org/problem?id=1141 题解:求已知子串最短的括号完备的全序列 代码: #include<iostream> #include<cst ...

  3. poj 1141 Brackets Sequence ( 区间dp+输出方案 )

    http://blog.csdn.net/cc_again/article/details/10169643 http://blog.csdn.net/lijiecsu/article/details ...

  4. 区间DP POJ 1141 Brackets Sequence

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29520   Accepted: 840 ...

  5. POJ 1141 Brackets Sequence (区间DP)

    Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a r ...

  6. POJ 1141 Brackets Sequence

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29502   Accepted: 840 ...

  7. poj 1141 Brackets Sequence(区间DP)

    题目:http://poj.org/problem?id=1141 转载:http://blog.csdn.net/lijiecsu/article/details/7589877 定义合法的括号序列 ...

  8. POJ 1141 Brackets Sequence(DP)

    题目链接 很早 很早之前就看过的一题,今天终于A了.状态转移,还算好想,输出路径有些麻烦,搞了一个标记数组的,感觉不大对,一直wa,看到别人有写直接输出的..二了,直接输出就过了.. #include ...

  9. POJ 1141 Brackets Sequence(括号匹配二)

    题目链接:http://poj.org/problem?id=1141 题目大意:给你一串字符串,让你补全括号,要求补得括号最少,并输出补全后的结果. 解题思路: 开始想的是利用相邻子区间,即dp[i ...

随机推荐

  1. python文件和目录操作方法大全

    一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法. 1.得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()2.返回指定目录下的所有文件和 ...

  2. jsp报源码

    刚在get的一个姿势.在参数后面加负号即爆出源码. w7oami 表哥解释道其原理如下: 1.用了@file_get_contents 函数 2.cdn 或者负载均衡 才导致爆出源码.

  3. size_t ssize_t socklen_t

    size_t 解释一:为了增强程序的可移植性,便有了size_t,它是为了方便系统之间的移植而定义的,不同的系统上,定义size_t可能不一样. 在32位系统上 定义为 unsigned int 也就 ...

  4. Java学习理解路线图

    信息来自知乎网友 学习截图:来自开源力量

  5. Lua中的loadfile、dofile、require详解

    1.loadfile——只编译,不运行 loadfile故名思议,它只会加载文件,编译代码,不会运行文件里的代码.比如,我们有一个hellofile.lua文件: 复制代码代码如下: print(“h ...

  6. The declared package &quot;com.dao&quot; does not match the expected package &quot;src.com.dao&quot;

    今天把项目代码上传到svn后出现例如以下错误:The declared package "com.dao" does not match the expected package ...

  7. mongodb查询之从多种分类中获取各分类最新一条记录

    mongodb查询之从多种分类中获取各分类最新一条记录 2017年04月06日 13:02:47 monkey_four 阅读数:6707更多 个人分类: MongoDBJavaScript   文章 ...

  8. PHPstorm8 自动换行设置方法

    PHPstorm是一款非常不错的PHP开发工具,有很多需要自己设置.比如,IDE常见的代码自动换行功能需要我们自己去配置才能实现. File -> Settings ->  Editor ...

  9. 上手并过渡到PHP7(2)——必须传递int, string, bool参数?没问题

    Type hints, Type safe 泊学实操视频 泊学原文链接PHP 7中最引人注目的新特性之一,无疑是Scalar type hints.我们可以在函数参数和返回值中使用scalar typ ...

  10. Quill + Framework 7 移动端无法获取焦点

    Quill 是一个轻量级的富文本编辑器.最近公司项目中需要用到这个东东.使用方法可以直接查看它的官网地址或者Github地址: Github地址:quilljs 官网地址:quill官网 主要说一下用 ...