思路:
斜率优化dp
s[i]表示1-i的前缀和
斜率不等式为:
对于 i < j < k
(dp[j] - dp[k] + (j + s[j])^2 - (k + s[k])^2) / ((j + s[j]) - (k + s[k])) <= 2*(i + s[i] - l -1)
#includeusing namespace std;#define fi first#define se second#define pi acos(-1.0)#define LL long long//#define mp make_pair#define pb push_back#define ls rt<<1, l, m#define rs rt<<1|1, m+1, r#define ULL unsigned LL#define pll pair #define pii pair #define piii pair #define mem(a, b) memset(a, b, sizeof(a))#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);//headconst int N = 5e4 + 5;int c[N], l;LL sum[N], dp[N];LL get_down(int j, int k) { return (j + sum[j] - (k + sum[k]));}LL get_up(int j, int k) { return dp[j] - dp[k] + (j + sum[j])*(j + sum[j]) - (k + sum[k])*(k + sum[k]);}int main() { int n; scanf("%d %d", &n, &l); for (int i = 1; i <= n; i++) scanf("%d", &c[i]); for (int i = 1; i <= n; i++) { sum[i] = sum[i-1] + c[i]; } deque q; q.push_front(0); for (int i = 1; i <= n; i++) { while(q.size() >= 2) { int t = q.front(); q.pop_front(); int tt = q.front(); if(get_up(tt, t) <= 2*(i + sum[i] - l - 1)*get_down(tt, t)); else { q.push_front(t); break; } } int t = q.front(); dp[i] = dp[t] + (i - t - 1 + sum[i] - sum[t] - l) * (i - t - 1 + sum[i] - sum[t] - l); while(q.size() >= 2) { int t = q.back(); q.pop_back(); int tt = q.back(); if(get_up(i, t) * get_down(t, tt) <= get_up(t, tt) * get_down(i, t)) ; else { q.push_back(t); break; } } q.push_back(i); } printf("%lld\n", dp[n]); return 0;}