Advertisement
kraskevich

Mining

Jul 24th, 2016
337
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.44 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5.  
  6. typedef long long ll;
  7.  
  8. const ll INF = (ll) 1e18;
  9.  
  10. const ll N = 5005;
  11.  
  12. ll x[N];
  13. ll w[N];
  14. ll P[N];
  15. ll S[N];
  16. int n;
  17.  
  18. vector<ll> newH;
  19. vector<ll> newF;
  20.  
  21. struct Line {
  22.     ll K;
  23.     ll B;
  24.    
  25.     Line(ll K = 0, ll B = 0): K(K), B(B) {}
  26. };
  27.  
  28. Line q[N];
  29.  
  30. double getInter(Line a, Line b) {
  31.     return (a.B - b.B) * 1.0 / (b.K - a.K);
  32. }
  33.  
  34. const double eps = 1e-9;
  35.  
  36. bool throwAway(const Line& a, const Line& b, const Line& c) {
  37.     double x_last = getInter(c, b);
  38.     double x_pred = getInter(a, b);
  39.     return x_pred - eps > x_last;
  40. }
  41.  
  42. ll calc(Line l, ll x) {
  43.     return l.K * x + l.B;
  44. }
  45.  
  46. struct LineDeque {
  47.     int head;
  48.     int tail;
  49.  
  50.     LineDeque(): head(0), tail(0) {}
  51.  
  52.     void add(Line newLine) {
  53.         while (head <= tail - 2 && throwAway(q[tail - 2], q[tail - 1], newLine))
  54.             tail--;
  55.         q[tail] = newLine;
  56.         tail++;
  57.     }
  58.  
  59.     ll getBest(ll x) {
  60.         while (head + 1 < tail && calc(q[head], x) >= calc(q[head + 1], x))
  61.             head++;
  62.         return calc(q[head], x);
  63.     }
  64. };
  65.  
  66. void calcLayer(vector<ll>& oldF, vector<ll>& oldH) {
  67.     fill(newH.begin(), newH.end(), INF);
  68.     newH[0] = 0;
  69.     fill(newF.begin(), newF.end(), INF);
  70.     LineDeque lf;
  71.     for (int i = 1; i <= n; i++) {
  72.         lf.add(Line(-S[i - 1], oldH[i - 1] + P[i - 1]));
  73.         newF[i] = lf.getBest(x[i]) + x[i] * S[i] - P[i];  
  74.     }
  75.     LineDeque lh;
  76.     for (int i = 1; i <= n; i++) {
  77.         lh.add(Line(-x[i], newF[i] - P[i - 1] + x[i] * S[i - 1]));
  78.         newH[i] = lh.getBest(S[i]) + P[i];
  79.     }
  80.     copy(newF.begin(), newF.end(), oldF.begin());
  81.     copy(newH.begin(), newH.end(), oldH.begin());
  82. }
  83.  
  84. int main() {
  85.     ios_base::sync_with_stdio(0);
  86.     int k;
  87.     cin >> n >> k;
  88.     newH.resize(n + 1);
  89.     newF.resize(n + 1);
  90.     for (int i = 1; i <= n; i++)
  91.         cin >> x[i] >> w[i];
  92.     for (int i = 1; i <= n; i++) {
  93.         P[i] = P[i - 1] + w[i] * x[i];
  94.         S[i] = S[i - 1] + w[i];  
  95.     }          
  96.     vector<ll> f(n + 1, INF);
  97.     for (int r = 1; r <= n; r++)
  98.         f[r] = P[0] - x[r] * S[0] + x[r] * S[r] - P[r];
  99.     vector<ll> h(n + 1, INF);
  100.     h[0] = 0;
  101.     for (int r = 1; r <= n; r++)
  102.         for (int l = 1; l <= r; l++)
  103.             h[r] = min(h[r], f[l] - P[l - 1] + x[l] * S[l - 1] - x[l] * S[r] + P[r]);
  104.     for (int i = 2; i <= k; i++)
  105.         calcLayer(f, h);
  106.     cout << h[n] << endl;
  107.     return 0;
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement