erek1e

IOI '00 P5 - Post Office (3)

Jun 10th, 2022 (edited)
1,651
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.44 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int INF = 1e9;
  6.  
  7. vector<int> x;
  8. int A(int l, int r) {
  9.     return (x[r]-x[r-(r-l+1)/2]) - (x[l+(r-l+1)/2-1]-x[l-1]);
  10. }
  11.  
  12. vector<vector<int>> dp, pos;
  13. void divideAndConquer(int i, int l, int r, int kl, int kr) {
  14.     if (l > r) return;
  15.     int j = (l+r)/2;
  16.     for (int k = kl; k <= kr; ++k) {
  17.         dp[i][j] = min(dp[i][j], dp[k][j-1] +  A(k+1, i));
  18.     }
  19.     for (int k = kl; k <= kr; ++k) {
  20.         if (dp[i][j] == dp[k][j-1] + A(k+1, i)) pos[i][j] = k;
  21.     }
  22.     divideAndConquer(i, l, j-1, kl, pos[i][j]);
  23.     divideAndConquer(i, j+1, r, pos[i][j], kr);
  24. }
  25.  
  26. int main() {
  27.     int n, m;
  28.     cin >> n >> m;
  29.     x.resize(1+n);
  30.     for (int i = 1; i <= n; ++i) cin >> x[i], x[i] += x[i-1];
  31.  
  32.     dp = vector<vector<int>>(1+n, vector<int>(1+n, INF));
  33.     pos = vector<vector<int>>(1+n, vector<int>(2+n));
  34.     for (int i = 1; i <= n; ++i) {
  35.         dp[i][1] = A(1, i);
  36.         pos[i][i+1] = i-1;
  37.     }
  38.  
  39.     for (int i = 2; i <= n; ++i) {
  40.         int l = 2, r = i; // values for j
  41.         int kl = 1, kr = i-1; // possible range of k (split) positions
  42.         divideAndConquer(i, l, r, kl, kr);
  43.     }
  44.  
  45.     cout << dp[n][m] << endl;
  46.     vector<int> v;
  47.     for (int i = n, j = m; j >= 1; i = pos[i][j--]) {
  48.         int k = (i + pos[i][j]+1)/2;
  49.         v.push_back(x[k]-x[k-1]);
  50.     }
  51.     for (int i = m-1; i >= 0; --i) cout << v[i] << ' ';
  52.     cout << endl;
  53.     return 0;
  54. }
Add Comment
Please, Sign In to add comment