-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path3826-minimum-partition-score.cpp
More file actions
59 lines (52 loc) · 1.66 KB
/
Copy path3826-minimum-partition-score.cpp
File metadata and controls
59 lines (52 loc) · 1.66 KB
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
class Solution {
public:
struct Line {
long long m, b;
long long calc(long long x) {
return m * x + b;
}
};
struct CHT {
deque<Line> dq;
bool bad(Line l1, Line l2, Line l3) {
return (l3.b - l1.b) * (l1.m - l2.m) <= (l2.b - l1.b) * (l1.m - l3.m);
}
void add(Line line) {
while (dq.size() >= 2 && bad(dq[dq.size() - 2], dq[dq.size() - 1], line)) {
dq.pop_back();
}
dq.push_back(line);
}
long long query(long long x) {
while (dq.size() >= 2 && dq[0].calc(x) >= dq[1].calc(x)) {
dq.pop_front();
}
return dq[0].calc(x);
}
};
long long minPartitionScore(vector<int>& nums, int k) {
const long long INF = 1e18 + 2;
int n = nums.size();
vector<long long> ps(n + 1);
for (int i = 0; i < n; i++) {
ps[i + 1] = ps[i] + nums[i];
}
// dp[t][i] - min score up to i using t splits
vector<vector<long long>> dp(k + 1, vector<long long>(n + 1, INF));
dp[0][0] = 0;
for (int t = 1; t <= k; t++) {
Line l0(-ps[0], dp[t - 1][0] + (ps[0] * ps[0] - ps[0]) / 2);
CHT cht;
cht.add(l0);
for (int i = 1; i <= n; i++) {
long long x = ps[i];
dp[t][i] = (x * x + x) / 2 + cht.query(x);
if (dp[t - 1][i] < INF) {
Line li(-ps[i], dp[t - 1][i] + (ps[i] * ps[i] - ps[i]) / 2);
cht.add(li);
}
}
}
return dp[k][n];
}
};