#include <cstdio> #include <vector> #include <queue> #include <set> #include <map> #include <unordered_map> using namespace std; const int N = 100000 + 9; int n; int k; char s[N]; vector<vector<int> > cnt; int diff(char c) { return c == '(' ? 1 : -1; } int max0[N]; map<pair<int, int>, int > mem; int solve(int i, int k) { if (i <= max0[k]) return 0; if (1 == k) return cnt[0][i]; pair<int, int> p{i, k}; if (mem.count(p) > 0) return mem[p]; int best = 999999999; for (int j=max0[k-1]+1; j<i; ++j) { int cur = solve(j - 1, k - 1) + cnt[j][i - j]; if (cur < best) best = cur; } mem[p] = best; return best; } int main() { scanf("%d%d%s", &n, &k, s); cnt.resize(n); for (int i=0; i<n; ++i) { cnt[i].push_back(0); unordered_map<int, vector<int> > um; um[0].push_back(i - 1); int lvl = diff(s[i]); um[lvl].push_back(i); for (int j=i+1; j<n; ++j) { lvl += diff(s[j]); int add = 0; if (um.count(lvl - 1) == 0) { add = um[lvl].size(); } else { int x = um[lvl - 1].back(); vector<int> &v = um[lvl]; int a = -1; int b = v.size(); while (a + 1 < b) { int c = (a + b) / 2; if (v[c] < x) a = c; else b = c; } add = v.size() - b; } add += cnt[i].back(); cnt[i].push_back(add); um[lvl].push_back(j); } } int st = 0; for (int x=1; x<=k; ++x) { int en = st; while (en < n && cnt[st][en - st] == 0) ++en; max0[x] = en - 1; st = en; } int res = solve(n - 1, k); printf("%d\n", res); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #include <cstdio> #include <vector> #include <queue> #include <set> #include <map> #include <unordered_map> using namespace std; const int N = 100000 + 9; int n; int k; char s[N]; vector<vector<int> > cnt; int diff(char c) { return c == '(' ? 1 : -1; } int max0[N]; map<pair<int, int>, int > mem; int solve(int i, int k) { if (i <= max0[k]) return 0; if (1 == k) return cnt[0][i]; pair<int, int> p{i, k}; if (mem.count(p) > 0) return mem[p]; int best = 999999999; for (int j=max0[k-1]+1; j<i; ++j) { int cur = solve(j - 1, k - 1) + cnt[j][i - j]; if (cur < best) best = cur; } mem[p] = best; return best; } int main() { scanf("%d%d%s", &n, &k, s); cnt.resize(n); for (int i=0; i<n; ++i) { cnt[i].push_back(0); unordered_map<int, vector<int> > um; um[0].push_back(i - 1); int lvl = diff(s[i]); um[lvl].push_back(i); for (int j=i+1; j<n; ++j) { lvl += diff(s[j]); int add = 0; if (um.count(lvl - 1) == 0) { add = um[lvl].size(); } else { int x = um[lvl - 1].back(); vector<int> &v = um[lvl]; int a = -1; int b = v.size(); while (a + 1 < b) { int c = (a + b) / 2; if (v[c] < x) a = c; else b = c; } add = v.size() - b; } add += cnt[i].back(); cnt[i].push_back(add); um[lvl].push_back(j); } } int st = 0; for (int x=1; x<=k; ++x) { int en = st; while (en < n && cnt[st][en - st] == 0) ++en; max0[x] = en - 1; st = en; } int res = solve(n - 1, k); printf("%d\n", res); return 0; } |