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. C/C++数组名与指针区别深入探索(转载)

    转载自: C/C++数组名与指针区别深入探索 引言 指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用.于是乎,很多程序设计者就被搞糊涂了.而许多的大学老师, ...

  2. 【转】Java对日期Date类进行加减运算,年份加减,月份加减

    import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date; public class Date ...

  3. python 高阶函数 map lambda filter等

    map 描述 map() 会根据提供的函数对指定序列做映射. 第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表. ...

  4. hdu 1007最近点对问题

    先说下题意,很简单,给n个点的坐标,求距离最近的一对点之间距离的一半.第一行是一个数n表示有n个点,接下来n行是n个点的x坐标和y坐标,实数. 这个题目其实就是求最近点对的距离.主要思想就是分治.先把 ...

  5. Python的内存管理 小理解

    请看下面的一段代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 origin = {'a':100,'b':[1,2,34,5]} obj_copy ={}; ...

  6. FreeRTOS 独立看门狗监测任务执行状态

    以下转载自安富莱电子: http://forum.armfly.com/forum.php 通过前面的几个章节,我们基本已经完成了 FreeRTOS 所有功能的讲解,本章节为大家介绍一种使用独立看门狗 ...

  7. Java调用存储过程小结

    学生在学习jdbc的时候,会问到怎么调用存储过程,现在将java调用oracle存储过程的示例总结如下.(关于调用sqlserver的存储过程将在下次进行小结请关注) 一:无返回值的存储过程 存储过程 ...

  8. 【WPF】Viewbox标签——控件大小适应父容器

    需求:图片拉伸至填满Image控件. 使用标签进行嵌套. <Grid> <Viewbox> <Image Name="myImage" /> & ...

  9. 统一处理jquery ajax请求过程中的异常错误信息的机制

    当jQuery ajax向服务器发送请求,服务器发生异常,比如:400.403.404.500等异常,服务器将异常响应给客户端,此时的ajax可以获取异常信息并进行处理,但此时我们一般是跳转到与异常编 ...

  10. BusyBox inittab配置

    inittab第一行指定初始化脚本,开启所有应用程序,必须有. ::sysinit:/etc/init.d/rcS 在第一行执行完后,执行剩余行命令,此终端要接受命令交互需开启sh. ::askfir ...