现在的位置: 首页 > 综合 > 正文

POJ 2955 Brackets (记忆化搜索)

2018年01月14日 ⁄ 综合 ⁄ 共 1123字 ⁄ 字号 评论关闭

题目类型  DP

题目意思
给出一个最长 100 的括号序列 问最长配对的括号子序列的长度是多少
括号的合法匹配有 () 和 [] 两种
例如 ((())) 最长是 6  而 [((]) 最长是 2

解题方法
记忆化搜索
参考代码 - 有疑问的地方在下方留言 看到会尽快回复的
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

char str[110];
int dp[110][110];

int DFS(int l, int r) {
	if(l >= r) return 0; // 肯定没配对
	if(r - l == 1) {
		if(str[l] == '(' && str[r] == ')') return 2; // 匹配返回2
		if(str[l] == '[' && str[r] == ']') return 2;
		return 0;
	}
	if(dp[l][r] != -1) return dp[l][r]; // 如果这段序列之前已经搜索过直接返回
	for( int i=l; i<=r; i++ ) {
		if(str[l] != '(' && str[l] != '[') dp[l][r] = max(dp[l][r], DFS(l+1, r)); // 如果序列的第一个不是左括号 直接去掉
		else {  // 否则找一个左括号来匹配
			if(str[l] == '(' && str[i] == ')') dp[l][r] = max(dp[l][r], 2 + DFS(l+1, i-1) + DFS(i+1, r));
			if(str[l] == '[' && str[i] == ']') dp[l][r] = max(dp[l][r], 2 + DFS(l+1, i-1) + DFS(i+1, r));
		}
		if(str[r] != ')' && str[r] != ']') dp[l][r] = max(dp[l][r], DFS(l, r-1));
		else {
			if(str[i] == '(' && str[r] == ')') dp[l][r] = max(dp[l][r], 2 + DFS(l, i-1) + DFS(i+1, r-1));
			if(str[i] == '[' && str[r] == ']') dp[l][r] = max(dp[l][r], 2 + DFS(l, i-1) + DFS(i+1, r-1));
		}
	}
	if(dp[l][r] == -1) dp[l][r] = 0;
	return dp[l][r];
}

int main() {
	freopen("in", "r", stdin);
	while(scanf("%s", str)) {
		if(strcmp(str, "end") == 0) break;
		memset(dp, -1, sizeof(dp));
		int len = strlen(str);
		int ans = DFS(0, len-1);
		printf("%d\n", ans);
	}
	return 0;
}

抱歉!评论已关闭.