#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; } |
English