第一题斜率优化DP,代码较搓OLZ…
AC code:
#include <cstdio>
typedef long long ll;
const int N=100010;
ll n,l;
ll c[N],s[N],f[N];
struct Vec{
ll x,y;
Vec() {}
Vec(ll x,ll y):x(x),y(y) {}
friend Vec operator-(Vec A,Vec B){
return Vec(A.x-B.x,A.y-B.y);
}
friend ll operator*(Vec A,Vec B){
return A.x*B.y-A.y*B.x;
}
};
struct Graham{
ll he,ta;
Vec q[N];
void push(Vec A){
while(ta-he&&(q[ta]-q[ta-1])*(A-q[ta])>=0) ta--;
q[++ta]=A;
}
}Q;
void read(){
scanf("%lld%lld",&n,&l);
for(ll i=1;i<=n;i++){
scanf("%lld",&c[i]);
s[i]=s[i-1]+c[i];
}
}
void work(){
Q.he=Q.ta=1;Q.q[1]=Vec(0,0);
ll pt=1;
for(ll i=1;i<=n;i++){
ll k=i+s[i]-l-1;
Vec v1,v2,u;
while(1){
if(pt==Q.ta) break;
v1=Q.q[pt];v2=Q.q[pt+1];
if(v1.y+2*k*v1.x<v2.y+2*k*v2.x) break;
pt++;
}
u=Q.q[pt];
f[i]=u.y+2*k*u.x+k*k;
Q.push(Vec(-i-s[i],f[i]+(i+s[i])*(i+s[i])));
}
printf("%lld\n",f[n]);
}
int main(){
read();
work();
return 0;
}