#include <iostream> #include <vector> #include <deque> #include <algorithm> #include <limits> using namespace std; const long long INF = numeric_limits<long long>::max() / 2; struct SuffixContainer { deque<int>dq{1}; long long good = 0; void shift_plus() { dq.push_front(1); } void shift_minus() { dq.pop_front(); if (dq.empty()) dq.push_front(0); good += dq.front(); dq.front()++; } int get_good() const { return good; } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k; string s; cin >> n >> k >> s; // find interesting points vector<int>Interest; for (int i = 1; i < n; i++) if (s[i-1] == '(' && s[i] == ')') Interest.push_back(i); if ((int)Interest.size() < k) { cout << "0\n"; return 0; } // make dp over interestiong points vector<vector<long long>>dp; vector<SuffixContainer>SC; dp.push_back(vector<long long>(k)); dp[0][0] = 0; for (int i = 1; i < k; i++) dp[0][i] = INF; SC.push_back(SuffixContainer()); int char_it = 0; for (int ip = 0; ip < (int)Interest.size(); ip++) { /* int ileft = Interest[ip] - 1; */ int iright = Interest[ip]; // update suffixes while (char_it < iright) { for (auto& sc : SC) if (s[char_it] == '(') sc.shift_plus(); else sc.shift_minus(); char_it++; } // calculate dp vector<long long> newcol(k); newcol[0] = INF; for (int kk = 1; kk < k; kk++) { newcol[kk] = INF; for (int i = dp.size() - 1; i >= 0 && newcol[kk] >= SC[i].get_good(); i--) newcol[kk] = min(newcol[kk], dp[i][kk-1] + SC[i].get_good()); } // add to structures dp.push_back(move(newcol)); SC.push_back(SuffixContainer()); } // choose the best solution while (char_it < n) { for (auto& sc : SC) if (s[char_it] == '(') sc.shift_plus(); else sc.shift_minus(); char_it++; } long long result = INF; for (int i = 0; i <= (int)Interest.size(); i++) result = min(result, dp[i][k-1] + SC[i].get_good()); cout << result << "\n"; 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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | #include <iostream> #include <vector> #include <deque> #include <algorithm> #include <limits> using namespace std; const long long INF = numeric_limits<long long>::max() / 2; struct SuffixContainer { deque<int>dq{1}; long long good = 0; void shift_plus() { dq.push_front(1); } void shift_minus() { dq.pop_front(); if (dq.empty()) dq.push_front(0); good += dq.front(); dq.front()++; } int get_good() const { return good; } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k; string s; cin >> n >> k >> s; // find interesting points vector<int>Interest; for (int i = 1; i < n; i++) if (s[i-1] == '(' && s[i] == ')') Interest.push_back(i); if ((int)Interest.size() < k) { cout << "0\n"; return 0; } // make dp over interestiong points vector<vector<long long>>dp; vector<SuffixContainer>SC; dp.push_back(vector<long long>(k)); dp[0][0] = 0; for (int i = 1; i < k; i++) dp[0][i] = INF; SC.push_back(SuffixContainer()); int char_it = 0; for (int ip = 0; ip < (int)Interest.size(); ip++) { /* int ileft = Interest[ip] - 1; */ int iright = Interest[ip]; // update suffixes while (char_it < iright) { for (auto& sc : SC) if (s[char_it] == '(') sc.shift_plus(); else sc.shift_minus(); char_it++; } // calculate dp vector<long long> newcol(k); newcol[0] = INF; for (int kk = 1; kk < k; kk++) { newcol[kk] = INF; for (int i = dp.size() - 1; i >= 0 && newcol[kk] >= SC[i].get_good(); i--) newcol[kk] = min(newcol[kk], dp[i][kk-1] + SC[i].get_good()); } // add to structures dp.push_back(move(newcol)); SC.push_back(SuffixContainer()); } // choose the best solution while (char_it < n) { for (auto& sc : SC) if (s[char_it] == '(') sc.shift_plus(); else sc.shift_minus(); char_it++; } long long result = INF; for (int i = 0; i <= (int)Interest.size(); i++) result = min(result, dp[i][k-1] + SC[i].get_good()); cout << result << "\n"; return 0; } |