AcWing 1094. 打印文章(斜率优化)
原题链接
中等
作者:
白墙
,
2021-07-20 20:15:54
,
所有人可见
,
阅读 341
#include <iostream>
#include <string>
#include <cstdio>
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 +10;
typedef long long ll;
//f[i] = min {f[k] + (s[i] - s[k])^2 + M};
//f[i] = f[k] + s[i]^2 + s[k]^2 - 2 * s[i] * s[k] + M
/*f[k] + s[k]^2 = f[i] + 2 * s[i] *s[k] - M
斜率:2 * s[i]
截距:f[i] - M
y: f[k] + s[k]^2
x:s[k]*/
int n, m;
ll f[N], c[N], s[N];
int q[N], tt, hh;
ll getY (int k) {
return f[k] + s[k] * s[k];
}
void solve() {
memset (s, 0, sizeof s);
for (int i = 1; i <= n; i ++) {
cin >> c[i];
s[i] = s[i - 1] + c[i];
}
memset(f, 0x3f, sizeof f);
f[0] = 0;
tt = hh = 0;
for (int i = 1; i <= n; i ++) {
while (hh < tt && (getY(q[hh + 1]) - getY(q[hh])) <= 2 * s[i] *(s[q[hh+1]] - s[q[hh]])) hh ++;
int k = q[hh];
f[i] = f[k] + (s[i] - s[k]) * (s[i] - s[k]) + m;
while (hh < tt && (getY(q[tt]) - getY(q[tt - 1])) * (s[i] - s[q[tt]])
>= (getY(i) - getY(q[tt])) * (s[q[tt]] - s[q[tt - 1]])) tt --;
q[++tt] = i;
}
cout <<f[n] << endl;
}
int main () {
while(cin >>n >>m) {
solve();
}
return 0;
}