#include <iostream> #include <map> #include <stack> #include <string> #include <unordered_map> typedef long long int i64; const i64 INF = 1LL << 60; using std::string; template <typename T> T min_of(T a, T b) { return a < b ? a : b; } template <typename T> T max_of(T a, T b) { return a > b ? a : b; } class Processor { i64 nawness; std::stack<i64> st; i64 at_level; int last; public: inline i64 _nawness() { return nawness; } Processor() : nawness(0), at_level(1), last(-1) {} i64 process(char c, int idx) { if (idx == last) { return _nawness(); } last = idx; if (c == '(') { st.push(at_level); at_level = 1; } else if (!st.empty()) { at_level = st.top(); st.pop(); nawness += at_level; at_level += 1; } else { at_level = 1; } return nawness; } }; i64 find_min(string &word, int start, int k, i64 budget) { static std::unordered_map<i64, i64> cache; i64 key = (i64)start << 32 | k; auto res = cache.find(key); if (res != cache.end()) { return res->second; } Processor proc; int end = word.length(); if (k == 0) { for (int i = start; i < end; ++i) { proc.process(word[i], i); } return cache[key] = proc._nawness(); } else { i64 min = INF; i64 rest = 0; i64 used = 0; for (int i = start; i < end; ++i) { while (proc.process(word[i], i) == used) { if (++i == end || used > budget || used >= min) { if (min == INF) { return cache[key] = 0; } else { return cache[key] = min; } } } --i; rest = find_min(word, i + 1, k - 1, budget); min = min_of(min, used + rest); used = proc._nawness(); } return cache[key] = min; } } int main() { int K; string word; std::cin >> K >> K; std::cin >> word; int right = 0; for (char c : word) { if (c == ')') { ++right; } } i64 len = ((word.length() / K) + 5 ) / 2; i64 budget = len * (len + 1) / 2; std::cout << find_min(word, 0, K - 1, budget) << "\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 106 107 | #include <iostream> #include <map> #include <stack> #include <string> #include <unordered_map> typedef long long int i64; const i64 INF = 1LL << 60; using std::string; template <typename T> T min_of(T a, T b) { return a < b ? a : b; } template <typename T> T max_of(T a, T b) { return a > b ? a : b; } class Processor { i64 nawness; std::stack<i64> st; i64 at_level; int last; public: inline i64 _nawness() { return nawness; } Processor() : nawness(0), at_level(1), last(-1) {} i64 process(char c, int idx) { if (idx == last) { return _nawness(); } last = idx; if (c == '(') { st.push(at_level); at_level = 1; } else if (!st.empty()) { at_level = st.top(); st.pop(); nawness += at_level; at_level += 1; } else { at_level = 1; } return nawness; } }; i64 find_min(string &word, int start, int k, i64 budget) { static std::unordered_map<i64, i64> cache; i64 key = (i64)start << 32 | k; auto res = cache.find(key); if (res != cache.end()) { return res->second; } Processor proc; int end = word.length(); if (k == 0) { for (int i = start; i < end; ++i) { proc.process(word[i], i); } return cache[key] = proc._nawness(); } else { i64 min = INF; i64 rest = 0; i64 used = 0; for (int i = start; i < end; ++i) { while (proc.process(word[i], i) == used) { if (++i == end || used > budget || used >= min) { if (min == INF) { return cache[key] = 0; } else { return cache[key] = min; } } } --i; rest = find_min(word, i + 1, k - 1, budget); min = min_of(min, used + rest); used = proc._nawness(); } return cache[key] = min; } } int main() { int K; string word; std::cin >> K >> K; std::cin >> word; int right = 0; for (char c : word) { if (c == ')') { ++right; } } i64 len = ((word.length() / K) + 5 ) / 2; i64 budget = len * (len + 1) / 2; std::cout << find_min(word, 0, K - 1, budget) << "\n"; return 0; } |