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
| // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
static const long long INF = (1LL << 62);
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int L, G;
if (!(cin >> L >> G)) return 0;
G = min(G, L);
vector<long long> C(L + 1, 0);
for (int i = 1; i <= L; ++i) cin >> C[i];
vector<long long> S(L + 1, 0);
for (int i = 1; i <= L; ++i) S[i] = S[i - 1] + C[i];
auto cost = [&](int l, int r) -> long long {
long long len = r - l + 1;
return len * (S[r] - S[l - 1]);
};
vector<long long> prev(L + 1, INF), cur(L + 1, INF);
prev[0] = 0;
function<void(int,int,int,int)> solve = [&](int Lx, int Rx, int optL, int optR) {
if (Lx > Rx) return;
int mid = (Lx + Rx) >> 1;
long long best = INF; int bestK = -1;
int sr = min(mid - 1, optR);
for (int k = optL; k <= sr; ++k) {
if (prev[k] == INF) continue;
long long cand = prev[k] + cost(k + 1, mid);
if (cand < best) { best = cand; bestK = k; }
}
cur[mid] = best;
solve(Lx, mid - 1, optL, (bestK == -1 ? optL : bestK));
solve(mid + 1, Rx, (bestK == -1 ? sr : bestK), optR);
};
for (int g = 1; g <= G; ++g) {
fill(cur.begin(), cur.end(), INF);
solve(1, L, 0, L - 1);
prev.swap(cur);
prev[0] = INF; // r>=g가 아니면 사실상 불가능 상태 유지
}
cout << prev[L] << '\n';
return 0;
}
|