斜率优化DP经典入门题,网上有大量题解
#include<cstdio>
typedef long long LL;
const int maxn=60000;
LL s[maxn],f[maxn],g[maxn],h[maxn];
int q[maxn],l,r;
int n,c;
inline void count(int i){
h[i]=f[i]+(g[i]+c)*(g[i]+c);
}
inline bool check(int i){
if (r-l+1<2) return false;
int j=q[r-1], k=q[r];
return (h[i]-h[k])*(g[k]-g[j]) <= (h[k]-h[j])*(g[i]-g[k]);
}
inline LL zy(int j, int i){
return f[j]+(g[i]-g[j]-c)*(g[i]-g[j]-c);
}
int main(){
scanf("%d%d",&n,&c);
c++;
for (int i=1;i<=n;i++){
int t; scanf("%d",&t);
s[i]=s[i-1]+LL(t);
}
count(0);
l=r=1; q[1]=0;
for (int i=1;i<=n;i++){
g[i]=s[i]+i;
while (l<r && zy(q[l],i)>=zy(q[l+1],i)) l++;
f[i]=zy(q[l],i);
count(i);
while (check(i)) r--;
q[++r]=i;
}
printf("%lld\n",f[n]);
return 0;
}