POJ 2955 Brackets (记忆化搜索)

来源:互联网 发布:西北师大知行学院萧泰 编辑:程序博客网 时间:2024/05/29 13:20
题目类型  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; // 匹配返回2if(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;}


0 0
原创粉丝点击