Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const int INF = 1e9;
- vector<int> x;
- int A(int l, int r) {
- return (x[r]-x[r-(r-l+1)/2]) - (x[l+(r-l+1)/2-1]-x[l-1]);
- }
- vector<vector<int>> dp, pos;
- void divideAndConquer(int i, int l, int r, int kl, int kr) {
- if (l > r) return;
- int j = (l+r)/2;
- for (int k = kl; k <= kr; ++k) {
- dp[i][j] = min(dp[i][j], dp[k][j-1] + A(k+1, i));
- }
- for (int k = kl; k <= kr; ++k) {
- if (dp[i][j] == dp[k][j-1] + A(k+1, i)) pos[i][j] = k;
- }
- divideAndConquer(i, l, j-1, kl, pos[i][j]);
- divideAndConquer(i, j+1, r, pos[i][j], kr);
- }
- int main() {
- int n, m;
- cin >> n >> m;
- x.resize(1+n);
- for (int i = 1; i <= n; ++i) cin >> x[i], x[i] += x[i-1];
- dp = vector<vector<int>>(1+n, vector<int>(1+n, INF));
- pos = vector<vector<int>>(1+n, vector<int>(2+n));
- for (int i = 1; i <= n; ++i) {
- dp[i][1] = A(1, i);
- pos[i][i+1] = i-1;
- }
- for (int i = 2; i <= n; ++i) {
- int l = 2, r = i; // values for j
- int kl = 1, kr = i-1; // possible range of k (split) positions
- divideAndConquer(i, l, r, kl, kr);
- }
- cout << dp[n][m] << endl;
- vector<int> v;
- for (int i = n, j = m; j >= 1; i = pos[i][j--]) {
- int k = (i + pos[i][j]+1)/2;
- v.push_back(x[k]-x[k-1]);
- }
- for (int i = m-1; i >= 0; --i) cout << v[i] << ' ';
- cout << endl;
- return 0;
- }
Add Comment
Please, Sign In to add comment