Topcoder SRM 301 Div2-1000 CorrectingParenthesization(區間DP)
阿新 • • 發佈:2018-02-04
完全 errors 實現 括號 cor ren opc fin 區間dp
題意 給定一個長度為偶數的字符串。這個字符串由三種括號組成。
現在要把這個字符串修改為一個符合括號完全匹配的字符串,改變一個括號的代價為$1$,求最小總代價。
區間DP。令$dp[i][j]$為把子序列$[i,j]$修改為符合要求的括號序列。
其中$cnt$為調整當前最外層的那對括號所需的最小代價。
那麽有狀態轉移方程$dp[i][j] = min(dp[i+1][j-1] + cnt, min{dp[i][k] + dp[k+1][j]})$
用記憶化搜索實現。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) const int N = 53; int f[N][N]; int a[N]; int n; int dp(int l, int r){ if (l > r) return 0; if (~f[l][r]) return f[l][r]; int cnt = 0; if (a[l] > 0 && a[r] < 0 && a[l] + a[r] == 0) cnt = 0; else if (a[l] > 0 || a[r] < 0) cnt = 1; else cnt = 2; int ret = dp(l + 1, r - 1) + cnt; for (int i = l + 1; i <= r - 1; i += 2) ret = min(ret, dp(l, i) + dp(i + 1, r)); return f[l][r] = ret; } class CorrectingParenthesization { public: int getMinErrors(string s){ memset(f, -1, sizeof f); n = s.size(); rep(i, 0, n - 1){ if (s[i] == ‘(‘) a[i + 1] = 1; else if (s[i] == ‘[‘) a[i + 1] = 2; else if (s[i] == ‘{‘) a[i + 1] = 3; else if (s[i] == ‘)‘) a[i + 1] = -1; else if (s[i] == ‘]‘) a[i + 1] = -2; else if (s[i] == ‘}‘) a[i + 1] = -3; } return dp(1, n); } };
Topcoder SRM 301 Div2-1000 CorrectingParenthesization(區間DP)