Advertisement
tien_noob

Circular barn - USACO - Convex Hull Trick

Oct 10th, 2021
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.85 KB | None | 0 0
  1. //Make CSP great again
  2. //You're as beautiful as the day I lost you
  3. #include <bits/stdc++.h>
  4. #define TASK "cbarn"
  5. using namespace std;
  6. const int N = 1e3, K = 7;
  7. const long long oo = 1e18;
  8. int a[2 * N + 1], n, k;
  9. long long b[N + 1], p[N + 1],res = oo;
  10. void read()
  11. {
  12.     cin >> n >> k;
  13.     for (int i = 1; i <= n; ++ i)
  14.     {
  15.         cin >> a[i];
  16.         a[n + i] = a[i];
  17.     }
  18. }
  19. struct Convex
  20. {
  21.     long long dp[N + 1];
  22.     long long A(int i)
  23.     {
  24.         return -(i - 1);
  25.     }
  26.     long long B(int i)
  27.     {
  28.         return dp[i - 1] - p[i - 1] + (i - 1) * b[i - 1];
  29.     }
  30.     long long C(int i)
  31.     {
  32.         return p[i];
  33.     }
  34.     long double Inter(int x, int y)
  35.     {
  36.         return (long double)(B(y) - B(x))/(A(x) - A(y));
  37.     }
  38.     vector<long double> Point;
  39.     vector<int> Line;
  40.     bool ok(int i)
  41.     {
  42.         return Inter(i, Line.back()) > Inter(i, Line[Line.size() - 2]);
  43.     }
  44.     void Init()
  45.     {
  46.         fill(dp, dp + n + 1, oo);
  47.         Point.clear();
  48.         Line.clear();
  49.     }
  50.     void add(int i)
  51.     {
  52.         while(Line.size() > 1 && !ok(i))
  53.         {
  54.             Point.pop_back();
  55.             Line.pop_back();
  56.         }
  57.         if (Line.empty())
  58.         {
  59.             Point.push_back(-1e18);
  60.         }
  61.         else
  62.         {
  63.             Point.push_back(Inter(i, Line.back()));
  64.         }
  65.         Line.push_back(i);
  66.     }
  67.     long long Get(int i)
  68.     {
  69.         int j = upper_bound(Point.begin(), Point.end(), (long double)(b[i])) - Point.begin() - 1;
  70.         return A(Line[j]) * b[i] + B(Line[j]) + C(i);
  71.     }
  72. };
  73. Convex CHT[K + 1];
  74. //dp[i][j] = min(dp[i][j], dp[h - 1][j - 1] + (p[i] - p[h - 1])- (h - 1) * (b[i] - b[h - 1]));
  75. void Update(int x)
  76. {
  77.     long long f[K + 1];
  78.     for (int j = 1; j <= k; ++ j)
  79.     {
  80.         CHT[j].Init();
  81.     }
  82.     CHT[1].dp[0] = 0;
  83.     for (int i = 1; i <= n; ++ i)
  84.     {
  85.         b[i] = b[i - 1] + a[x];
  86.         p[i] = p[i - 1] + 1LL * (i - 1) * a[x];
  87.         //cerr << a[x] << ' ';
  88.         ++x;
  89.     }
  90.     CHT[1].add(1);
  91.     for (int i = 2; i <= n; ++ i)
  92.     {
  93.          CHT[1].dp[i] = p[i];
  94.          f[1] = p[i];
  95.          for (int j = 2; j <= min(i, k); ++ j)
  96.          {
  97.              CHT[j - 1].add(i - 1);
  98.              f[j] = CHT[j - 1].Get(i);
  99.              CHT[j].dp[i] = f[j];
  100.          }
  101.     }
  102.     res = min(res, f[k]);
  103. }
  104. void solve()
  105. {
  106.     for (int i = 1; i <= n; ++ i)
  107.     {
  108.         Update(i);
  109.     }
  110.     cout << res;
  111. }
  112. int main()
  113. {
  114.     ios_base::sync_with_stdio(false);
  115.     cin.tie(nullptr);
  116.     if (fopen(TASK".in", "r"))
  117.     {
  118.         freopen(TASK".in", "r", stdin);
  119.         freopen(TASK".out", "w", stdout);
  120.     }
  121.     int t = 1;
  122.     bool typetest = false;
  123.     if (typetest)
  124.     {
  125.         cin >> t;
  126.     }
  127.     for (int __ = 1; __ <= t; ++ __)
  128.     {
  129.         //cout << "Case " << __ << ": ";
  130.         read();
  131.         solve();
  132.     }
  133. }
  134.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement