站在巨人肩上!
以后怎么用:
但凡出现dp得分计算公式中有平方,可以化简成为:
的形式就可以用斜率优化
斜率优化的精髓就在将上面的公式求出来,并且利用单调队列
#include<cstdio>
using namespace std;
int n,L;
long long C[100100];
long long dp[100100];
inline long long A(int x){return (long long)C[x];}
inline long long g(int x){return (long long)A(x)+L;}
inline long double slope(int j,int k){return (long double)(dp[j]-dp[k]+g(j)*g(j)-g(k)*g(k))/(A(j)-A(k))*1.0;}
int q[100100];
int h,t;
int main(void)
{
scanf("%d %d",&n,&L);L++;
for(int i=1;i<=n;i++){
scanf("%lld",&C[i]);
C[i]+=C[i-1]+1;
}
// h=1;
// t++;
// q[t]=0;
for(int i=1;i<=n;i++){
while(h<t && slope(q[h],q[h+1])<=2ll*C[i])h++;
dp[i]=dp[q[h]]+(long long)(A(i)-A(q[h])-L)*(A(i)-A(q[h])-L);
while(h<t && slope(q[t-1],q[t])>=slope(q[t-1],i))t--;
t++;q[t]=i;
}
printf("%lld",dp[n]);
}