bzoj1010: [HNOI2008]玩具装箱toy dp+斜率优化
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
#define maxn 100000
int n;
ll l;
ll c[maxn];
ll X[maxn],Y[maxn];
ll f[maxn];
int bo,he,qu[maxn];
int main(){
scanf("%d%lld",&n,&l);
for(int i=1;i<=n;i++){
int a;
scanf("%d",&a);
c[i]=c[i-1]+a;
}
ll p;
qu[he=bo=1]=0;
for(int i=1;i<=n;i++){
p=i-1+c[i]-l;
while(he>bo&&(Y[qu[bo+1]]-Y[qu[bo]])<=p*2*(X[qu[bo+1]]-X[qu[bo]]))bo++;
f[i]=Y[qu[bo]]+p*p-2*p*X[qu[bo]];
X[i]=i+c[i];
Y[i]=X[i]*X[i]+f[i];
while(he>bo&&(double)(Y[qu[he]]-Y[qu[he-1]])/double(X[qu[he]]-X[qu[he-1]])>=double(Y[i]-Y[qu[he]])/double(X[i]-X[qu[he]]))he--;
qu[++he]=i;
}
cout<<f[n];
}