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
| #define MAXN 500005 #define MAXM 1000005 int n, k; int x[MAXN], pre[MAXN], dp[MAXN];
struct Line { int a, b; int operator ()(int _x) { return a * _x + b; } };
bool check(Line l1, Line l2, Line l3, int _x) { return ((l1.b - l2.b) * (l3.a - l2.a) > (l2.a - l1.a) * (l2.b - l3.b) && (_x + k) * (l3.a - l2.a) > (l2.b - l3.b)); }
void sol() { cin >> n >> k; for (int i = 1; i <= n; i++) cin >> x[i]; reverse(x + 1, x + n + 1); for (int i = 1; i <= n; i++) pre[i] = pre[i - 1] + x[i];
deque<pair<Line, int>> dq; dq.push_back({{0, 0}, 0});
for (int i = 1; i <= n; i++) { while (dq.size() && dq.front().S < i - k) dq.pop_front(); while (dq.size() >= 2 && dq[0].F(i) < dq[1].F(i)) dq.pop_front();
dp[i] = -i * i + dq.front().F(i);
Line now = {2 * i, dp[i] - i * i + pre[i]}; while (dq.size() >= 2 && check(dq[dq.size() - 2].F, dq[dq.size() - 1].F, now, dq[dq.size() - 2].S)) dq.pop_back(); dq.push_back({now, i}); } cout << dp[n] << endl; }
|