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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <bits/stdc++.h>
using namespace std;
 
using ll = long long;
using db = double;
using ull = unsigned long long;
 
using pi = pair<int, int>;
using pl = pair<ll, ll>;
 
using vi = vector<int>;
using vl = vector<ll>;
using vpi = vector<pi>;
using vpl = vector<pl>;
 
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define f first
#define s second
 
#define tcT template<class T
#define tcTU tcT, class U
 
#define sz(x) int((x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i,a,b) for(int i = (a); i < (b); i++)
#define rrep(i,a,b) for(int i = (b) - 1; i >= (a); i--)
 
const db PI = acos(-1);
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
 
tcT> bool ckmin(T& a, const T& b) { return b < a ? a=b, 1 : 0; }
tcT> bool ckmax(T& a, const T& b) { return a < b ? a=b, 1 : 0; }
 
tcT> void _dbg(const char *sdbg, T h){ cerr<<sdbg<<'='<<h<<endl; }
tcT, class... TA> void _dbg(const char *sdbg, T h, TA... a) {
	while(*sdbg!=',') cerr<<*sdbg++;
	cerr<<'='<<h<<','; _dbg(sdbg+1, a...);
}
 
tcT> ostream &operator<<(ostream& os, vector<T> V) {
	os << "["; for (auto vv : V) os << vv << ","; return os << "]";
}
tcT, class V> ostream &operator<<(ostream &os, pair<T,V> P) {
	return os << "(" << P.f << "," << P.s << ")";
}
 
#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (__VA_ARGS__)
#define cerr if(0)cout
#endif

constexpr ll INF = 1e12+10;
int n, K;
string s;
vi a;
vector<vl> how_many_good;

void precalc() {
	rep(r,1,n) {
		int sum = -a[r];
		int cnt = 0;
		bool already_bad = (sum < 0);
		rrep(l,0,r) {
			if (!already_bad) {
				sum -= a[l];
				if (sum == 0) cnt++;
				if (sum < 0) already_bad = true;
			}
			how_many_good[l][r] = how_many_good[l][r-1] + cnt;
		}
	}
}

vl dp_before;
vl dp_cur;

void compute(int l, int r, int optl, int optr) {
	if (l > r) return;

	int mid = (l + r) / 2;

	pair<ll, int> best = mp(INF, -1);

	for (int k = optl; k <= min(mid, optr); k++) {
		best = min(best, mp((k ? dp_before[k-1] : 0) + how_many_good[k][mid], k));
	}

	dp_cur[mid] = best.f;
	int opt = best.s;

	compute(l, mid - 1, optl, opt);
	compute(mid + 1, r, opt, optr);
}

signed main() {
	ios_base::sync_with_stdio(false); cin.tie(nullptr);
	
	cin >> n >> K;
	cin >> s;

	a.resize(n);
	how_many_good.resize(n, vl(n+1, 0));
	dp_before.resize(n);
	dp_cur.resize(n);

	rep(i,0,n) {
		a[i] = (s[i] == '(' ? 1 : -1);
	}

	precalc();

	rep(i,0,n) {
		dp_before[i] = how_many_good[0][i];
	}

	rep(i,1,K) {
		compute(0,n-1,0,n-1);
		dp_before = dp_cur;
	}

	cout << dp_before[n-1] << "\n";

	return 0;
}