斜率优化DP裸题,DP方程很简单就不给了
优化一下,整理式子成y=kx+b的形式
发现x单调递增,斜率k单调递减,用一个队列维护凸包就行啦
f[i]和b成正比,而f[i]期望最大值,所以维护上凸包
#include <cstdio>
#include <algorithm>
#include <cstring>
#define il inline
#define ll long long
#define N 1001000
using namespace std;
//re
int n;
ll A,B,C;
int que[N];
ll f[N],d[N],sum[N];
int gc()
{
int rett=0,fh=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
while(c>='0'&&c<='9'){rett=(rett<<3)+(rett<<1)+c-'0';c=getchar();}
return rett*fh;
}
il ll yy(int i){return f[i]+A*sum[i]*sum[i]-B*sum[i]+C;}
il ll xx(int i){return sum[i];}
int main()
{
n=gc(),A=gc(),B=gc(),C=gc();
for(int i=1;i<=n;i++) d[i]=gc();
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+d[i];
int hd=1,tl=1;
for(int i=1;i<=n;i++)
{
while(hd+1<=tl&&yy(que[hd])-(ll)2*A*sum[i]*xx(que[hd]) <= yy(que[hd+1])-(ll)2*A*sum[i]*xx(que[hd+1]))
hd++;
f[i]=yy(que[hd])-(ll)2*A*sum[i]*xx(que[hd])+A*sum[i]*sum[i]+B*sum[i];
while(hd+1<=tl&& (yy(i)-yy(que[tl]))*(xx(que[tl])-xx(que[tl-1])) >= (yy(que[tl])-yy(que[tl-1]))*(xx(i)-xx(que[tl])))
tl--;
que[++tl]=i;
}
printf("%lld\n",f[n]);
return 0;
}