#include <iostream>
#include <vector>
const long long NEGINFINITY = -1000000000000000ll;
int main() {
int n, k;
std::cin >> n >> k;
std::vector<long long> v(n);
for (int i = 0; i < n; ++i) std::cin >> v[i];
std::vector<long long> p(n + 1);
for (int i = 1; i <= n; ++i) p[i] = p[i - 1] + v[i - 1];
/*
dp[kk][i] is the best value using kk splits with last one 'at' i
so if we know dp[kk-1] for all i, then we can calculate dp[kk][i] as:
max from prev=0 to prev = i-1 of (dp[kk-1][prev] + (p[i] - p[prev]) * (p.back() - p[i]))
*/
std::vector<std::vector<long long>> dp(k+2, std::vector<long long>(n+1));
std::vector<std::vector<int>> bestfrom(k+2, std::vector<int>(n+1));
/*
when kk=0, it must be that we can get no score
*/
for (int i = 0; i <= n; ++i) dp[0][i] = 0;
/*
when i = 0 but kk > 0 then we cannot even do anything, not even score 0
*/
for (int kk = 1; kk <= k+1; ++kk) dp[kk][0] = NEGINFINITY;
for (int kk = 1; kk <= k+1; ++kk) {
for (int i = 1; i <= n; ++i) {
dp[kk][i] = -1;
for (int prev = 0; prev < i; ++prev) {
long long candidate = dp[kk-1][prev] + (p[i] - p[prev])*(p.back() - p[i]);
if (candidate > dp[kk][i]) {
dp[kk][i] = candidate;
bestfrom[kk][i] = prev;
}
}
}
}
std::cout << dp[k+1][n] << '\n';
int cur = bestfrom[k+1][n];
while (k) {
std::cout << cur << " \n"[k==1];
cur = bestfrom[k][cur];
--k;
}
}
# | 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... |