이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define FR(i, N) for (int i = 0; i < int(N); i++)
#define all(x) begin(x), end(x)
using namespace std;
using ll = long long;
const int MAXN = (int)(1e5) + 5;
const int MAXK = 200+5;
int opt[MAXN][MAXK];
ll last[MAXN];
ll dp[MAXN];
//ll dp[MAXN][MAXK];
ll arr[MAXN];
ll prefSum[MAXN];
ll pref[MAXN];
ll calc(int l, int r) {
if (l == 0) {
return pref[r];
}
else {
return pref[r] - (prefSum[r]-prefSum[l-1])*prefSum[l-1] - pref[l-1];
}
}
void recur(int k, int tl, int tr, int l, int r) {
if (tl > tr) {
return;
}
int tm = (tl + tr)/2;
ll best = (ll)(1e18);
int id = -1;
for (int i = min(r, tm-1); i >= l; i--) {
if (last[i] + calc(i+1, tm) < best) {
best = last[i] + calc(i+1, tm);
id = i;
}
}
opt[tm][k] = id;
dp[tm] = best;
recur(k, tl, tm-1, l, id);
recur(k, tm+1, tr, id, r);
}
int main() {
cin.tie(0);
cin.sync_with_stdio(0);
int N, K;
cin >> N >> K;
ll sm = 0;
FR(i, N) {
cin >> arr[i];
last[i] = (i > 0 ? last[i-1] : 0) + arr[i]*sm;
pref[i] = last[i];
opt[i][0] = -1;
sm += arr[i];
prefSum[i] = sm;
}
for (int i = 1; i <= K; i++) {
recur(i, 0, N-1, 0, N-1);
swap(dp, last);
}
cout << pref[N-1] - last[N-1] << '\n';
int u = N-1;
for (int iter = K; iter >= 1; iter--) {
cout << opt[u][iter]+1 << '\n';
u = opt[u][iter];
}
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |