Advertisement
volochai

EJOI 2018 A

Aug 7th, 2022
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.83 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int N = 5e3 + 128;
  6. const int K = (N + 1) / 2;
  7. int dp[N][K][2];
  8. int p[N][K][2][3];
  9. int A[N];
  10.  
  11. const int INF = 1e9;
  12.  
  13. void solve() {
  14.     int n;
  15.     cin >> n;
  16.     for (int i = 1; i <= n; i++)
  17.         cin >> A[i];
  18.  
  19.     for (int i = 0; i <= n; i++)
  20.         for (int j = 0; j <= (n + 1) / 2; j++)
  21.             for (int k = 0; k < 2; k++)
  22.                 dp[i][j][k] = INF;
  23.  
  24.     dp[0][0][0] = dp[0][0][1] = 0;
  25.     for (int i = 1; i <= n; i++) {
  26.         for (int j = 0; j <= (n + 1) / 2; j++) {
  27.             p[i][j][0][0] = i - 1;
  28.             p[i][j][0][1] = j;
  29.             if (dp[i-1][j][0] < dp[i-1][j][1]) {
  30.                 dp[i][j][0] = dp[i-1][j][0];
  31.                 p[i][j][0][2] = 0;
  32.             } else {
  33.                 dp[i][j][0] = dp[i-1][j][1];
  34.                 p[i][j][0][2] = 1;
  35.             }
  36.         }
  37.  
  38.         int needLeft = 0;
  39.         if (i > 1)
  40.             needLeft += max(0, A[i - 1] - A[i] + 1);
  41.         int needRight = 0;
  42.         if (i < n)
  43.             needRight += max(0, A[i + 1] - A[i] + 1);
  44.  
  45.         for (int j = 1; j <= (n + 1) / 2; j++) {
  46.             p[i][j][1][0] = i - 1;
  47.             p[i][j][1][1] = j - 1;
  48.             p[i][j][1][2] = 0;
  49.             if (j == 1 || i <= 2 || p[i-1][j-1][0][0] != i - 2 || p[i-1][j-1][0][1] != j - 1 || p[i-1][j-1][0][2] != 1) {
  50.                 dp[i][j][1] = dp[i-1][j-1][0] + needLeft + needRight;
  51.             } else {
  52.                 int val = min(A[i - 1], A[i - 2] - 1);
  53.                 // A[i - 1] = val
  54.                 int exNeed = max(0, val - A[i] + 1);
  55.                 dp[i][j][1] = dp[i-1][j-1][0] + exNeed + needRight;
  56.             }
  57.         }
  58.     }
  59.  
  60.     for (int i = 1; i <= (n + 1) / 2; i++) {
  61.         cout << min(dp[n][i][0], dp[n][i][1]) << ' ';
  62.     }
  63. }
  64.  
  65. main() {
  66.     solve();
  67.     return 0;
  68. }
  69.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement