玩具裝箱TOY[斜率優化]
阿新 • • 發佈:2018-11-19
第一次自己推斜率優化,好高興
對於區間的長度,s[i]表示字首和在加上i
也就是
首先,考慮暴力的DP
拆開
整理成如下形式
也就是
最小值維護下凸包
#include<bits/stdc++.h> #define y(A) (f[A]+s[A]*s[A]+s[A]) #define k(A) (2*s[A]-2*L) #define x(A) (s[A]) #define N 50005 #define inf 1000000000000000 #define LL long long using namespace std; LL n,L,s[N],f[N],q[N]; double K(int i,int j){return 1.0*(y(j)-y(i))/(x(j)-x(i));} int main(){ scanf("%lld%lld",&n,&L); for(int i=1;i<=n;i++){ LL x; scanf("%lld",&x); s[i]=s[i-1]+x; } for(int i=1;i<=n;i++) s[i]+=i; int l=1,r=1; for(int i=1;i<=n;i++){ while(l<r && K(q[l],q[l+1]) <= k(i)) l++; f[i] = f[q[l]] + (s[i]-s[q[l]]-L-1)*(s[i]-s[q[l]]-L-1); while(l<r && K(q[r],i) <= K(q[r-1],q[r])) r--; q[++r] = i; }printf("%lld",f[n]); return 0; }