217人阅读 评论(0)

# 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，明天再把它切一遍

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：81679次
• 积分：1430
• 等级：
• 排名：千里之外
• 原创：62篇
• 转载：2篇
• 译文：0篇
• 评论：17条
最新评论