1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include <bits/stdc++.h> using namespace std; using ll = long long; const int N = 1e5 + 5; int n, h[N]; ll w[N], dp[N]; bool Cmp; struct Line { mutable ll k, b, p; bool operator < (const Line& oth) const { return Cmp ? p < oth.p : k < oth.k; } }; struct ConvecHull : multiset<Line> { static const ll inf = LLONG_MAX; ll div(ll a, ll b) { if(!b) return a>0 ? inf : -inf; return a / b - ((a ^ b) < 0 && a % b); } bool isect(iterator x, iterator y) { if (y == end()) { x->p = inf; return false; } if (x->k == y->k) x->p = x->b > y->b ? inf : -inf; else x->p = div((y->b - x->b), (x->k - y->k)); return x->p >= y->p; } void add(ll k, ll b) { auto z = insert({k, b, 0}), y = z++, x = y; while (isect(y, z)) z = erase(z); if (x != begin() && isect(--x, y)) isect(x, y = erase(y)); while ((y = x) != begin() && (--x)->p >= y->p) isect(x, erase(y)); } ll qry(ll x) { Cmp = 1; auto l = *lower_bound({0, 0, x}); Cmp = 0; return l.k * x + l.b; } }ch; int main() { scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d", h+i); for(int i=1; i<=n; i++) scanf("%lld", w+i), w[i] += w[i-1]; ch.add(2*h[1], -1ll*h[1]*h[1]+w[1]); for(int i=2; i<=n; i++) { dp[i] = -ch.qry(h[i]) + w[i-1] + 1ll*h[i]*h[i]; ch.add(2*h[i], -1ll*h[i]*h[i]+w[i]-dp[i]); } printf("%lld\n", dp[n]); return 0; }
|