# Brackets

 My Tags (Edit)
 Source : Stanford ACM Programming Contest 2004 Time limit : 1 sec Memory limit : 32 M

Submitted : 172, Accepted : 101

5.1 Description

We give the following inductive definition of a “regular brackets” sequence:

• the empty sequence is a regular brackets sequence,

• if s is a regularbrackets 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.

5.2 Example

Given the initial sequence ([([]])], the longest regular brackets subsequence is [([])].

5.3 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. For example:

((()))
()()()
([]])
)[)(
([][][)
end


5.4 Output

For each input case, the program should print the length of the longest possible regular brackets subsequence on a single line. For example:

6
6
4
0
6


/*较高效的非递归的写法*/

/*用递归还有一个0.57秒的写法，感觉还是很不错的思想，

* 虽然递归慢很多，不过记忆的方法就加速使其没有超时*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
const int MAX = 110;
char c[MAX];
int dp[MAX][MAX];

int main() {
while (scanf(" %s", &c) && c[0] != 'e') {
int size = strlen(c);
memset(dp, 0, sizeof (dp));

for (int step = 1; step < size; step++) {
for (int start = 0; start + step < size; start++) {
int end = start + step;
if ((c[start] == '[' && c[end] == ']') || (c[start] == '(' && c[end] == ')')) {
dp[start][end] = dp[start + 1][end - 1] + 1;
}
for (int mid = start; mid < end; mid++) {/*注意：mid从start开始，注意宁多勿少，因为可能会少考虑一些情况*/
dp[start][end] = max(dp[start][end], dp[start][mid] + dp[mid + 1][end]);
}
}
}
printf("%d\n", 2 * dp[0][size - 1]);
}
return 0;

}

/*很有成就感的递归写法，忽然间使用记忆的方法进行减枝同样可以AC*/

#include <iostream>
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int MAX = 110;
int a[MAX];
int b[MAX];
bool color_a[MAX];
bool color_b[MAX];
int size_a;
int size_b;
char c[MAX];

void init(int size_c) {
memset(color_a, 0, sizeof (color_a));
memset(color_b, 0, sizeof (color_b));
size_a = 0;
size_b = 0;
for (int i = 0; i < size_c; i++) {
if (c[i] == ')') {
a[size_a++] = i;
} else if (c[i] == ']') {
b[size_b++] = i;
}
}
}
int d[MAX][MAX];

int DFS(int start, int end) {
if (start >= end) return 0;
if (d[start][end] > 0) return d[start][end] - 1;
int min_size = 0;
for (int i = start; i <= end; i++) {
if (c[i] == '(') {
for (int j = 0; j < size_a && a[j] <= end; j++) {
if (a[j] > i && color_a[j] == false) {
color_a[j] = true;
min_size = max(min_size, 2 + DFS(start, i - 1) + DFS(i + 1, a[j] - 1) + DFS(a[j] + 1, end));
color_a[j] = false; //现场还原
}
}
} else if (c[i] == '[') {
for (int j = 0; j < size_b && b[j] <= end; j++) {
if (b[j] > i && color_b[j] == false) {
color_b[j] = true;
min_size = max(min_size, 2 + DFS(start, i - 1) + DFS(i + 1, b[j] - 1) + DFS(b[j] + 1, end));
color_b[j] = false; //现场还原
}
}
}
}
d[start][end] = min_size + 1;
return min_size;
}

int main() {
while (scanf(" %s", &c) && c[0] != 'e') {
int size_c = strlen(c);
init(size_c);

memset(d, 0, sizeof (d));
printf("%d\n", DFS(0, size_c - 1));
}
return 0;
}

Brackets Sequence，明天再把它切一遍

• 本文已收录于以下专栏：

## Codeforces Round #343 (Div. 2) C. Famil Door and Brackets（dp）

• lwt36
• 2016年02月26日 23:09
• 200

## Codeforces Round #106(Div. 2) 149D. Coloring Brackets 区间DP 记忆化搜索

D. Coloring Brackets time limit per test 2 seconds memory limit per test 256 megabytes ...

## 【POJ 2955】Brackets（区间DP）

【POJ 2955】Brackets（区间DP）入门级区间DP问最长的匹配括号长度。只包含()和[] 要求匹配括号不可交叉，即([)]这种不计入因为不计交叉情况，转移就很直白。枚举区间长度l，转移为...

## POJ 2955 Brackets 【区间dp】【水题】

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8027   Accepted: 4264 ...
• Archger
• 2017年07月13日 18:27
• 109

## POJ 1141 Brackets Sequence (区间DP)

﻿﻿ 这是一道挺好的区间DP题，类似往一个序列里插入东西的问题都可以往从中间分开考虑两块这个方向去想。 dp[i][j]表示i到j这一段最少需要插入括号的数量，显然这个数等于min(dp[i][k...

举报原因： 您举报文章：Brackets-学习DP2 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)