1. 程式人生 > >Brackets POJ - 2955 區間dp

Brackets POJ - 2955 區間dp

題解

題目大意 給一行括號進行配對 問這行括號的最大配對數量 (()也算是有一對匹配成功

使用區間dp求解 d[i][j]表示從i到j範圍內的括號配對數量
按照一般套路列舉區間長度和區間起點 再列舉區間中點取最大值合併兩個區間
當d[i][j]的最外層括號s[i]與s[j]配對則通過內層+2轉移過來 即
d[i][j] = max(d[i][j], d[i + 1][j - 1] + 2)
不用擔心i + 1反而大於j - 1的情況 那樣值為0不影響結果

AC程式碼

#include <iostream>
#include <string.h>
#include <stdio.h> #include <algorithm> using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int MAXN = 110; char s[MAXN]; int d[MAXN][MAXN]; //i到j範圍內括號是配對的 int main() { #ifdef LOCAL freopen("C:/input.txt", "r", stdin); #endif while (scanf("%s", s + 1) != EOF, s[1
] != 'e') { memset(d, 0, sizeof(d)); //單個括號不可能配對 int N = strlen(s + 1); int ans = 0; for (int l = 2; l <= N; l++) //區間長度 for (int i = 1; i + l - 1 <= N; i++) //區間起點 { int j = i + l - 1; //區間終點 for (int k = i; k < j; k++) //區間最值合併 d[i][j] = max(d[i][j], d[i][k] + d[k + 1][j])
; if (s[i] == '(' && s[j] == ')' || s[i] == '[' && s[j] == ']') //最外層括號配對 d[i][j] = max(d[i][j], d[i + 1][j - 1] + 2); //則從內部轉移 ans = max(ans, d[i][j]); } cout << ans << endl; } return 0; }