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. js switch的使用 ng-switch的使用方法

    语法 switch(n) { case 1: 执行代码块 1 break; case 2: 执行代码块 2 break; default: n 与 case 1 和 case 2 不同时执行的代码 } ...

  2. linux使用记录(一)

    1.tar #解压tar –xvf file.tar #解压 tar包 tar -xzvf file.tar.gz #解压tar.gz tar -xjvf file.tar.bz2 #解压 tar.b ...

  3. JDBC的介绍2

    一.基础知识 1. 数据持久化 持久化(persistence):对象在内存中创建后,不能永久存在.把对象永久的保存起来就是持久化的过程.而持久化的实现过程大多通过各种关系数据库来完成. 持久化的主要 ...

  4. Android——数据存储:手机外部存储 SD卡存储

    xml <EditText android:layout_width="match_parent" android:layout_height="wrap_cont ...

  5. u-boot可ping通PC,PC不可ping通u-boot

    http://blog.csdn.net/ce123_zhouwei/article/details/7339134 开发板运行U-Boot,在终端下使用Ping命令是能Ping通PC机,但PC机Pi ...

  6. 轻量级ORM框架Dapper应用二:使用Dapper实现CURD操作

    在上一篇文章中,讲解了如何安装Dapper,这篇文章中将会讲解如何使用Dapper使用CURD操作. 例子中使用到的实体类定义如下: using System; using System.Collec ...

  7. Linux - tar命令 压缩 和 解压

    压缩 tar -cvf jpg.tar *.jpg //将目录里所有jpg文件打包成tar.jpg tar -czf jpg.tar.gz *.jpg //将目录里所有jpg文件打包成jpg.tar后 ...

  8. 运行带distance field的Hiero

    从http://libgdx.badlogicgames.com/releases/下载zip包并解压,切换到解压后的目录,执行: java -cp gdx.jar;gdx-natives.jar;g ...

  9. Jquery与.net MVC结合,通过Ajax

    在工作中做了这么一个东西. Html端: @using Test.fh.Project.Storefront.ViewModels @using Test.fh.Project.Storefront. ...

  10. ubuntu配置apache和cgi

    ubuntu配置apache和cgi . 更新源并进行安装,否则后面的下载可能会不成功. sudo apt-get update sudo apt-get upgrade . 安装apache2服务 ...