传送门
http://www.lydsy.com/JudgeOnline/problem.php?id=1911
题目大意
把连续的人分组,每组[j,k]的价值为a(∑ki=jx[i])2+b∑ki=jx[i]+c询问所有组的价值和的最大值
题解
dp[i]=max{dp[j]+a∗(sum[i]−sum[j])2+b∗(sum[i]−sum[j])+c}
dp[i]=max{dp[j]−2a∗sum[i]sum[j]+sum[j]2−b∗sum[j]}+a∗sum[i]2+b∗sum[i]+c
考虑斜率优化
假设j<k且k更优
dp[j]−2a∗sum[i]sum[j]+sum[j]2−b∗sum[j]<=dp[k]−2a∗sum[i]sum[k]+sum[k]2−b∗sum[k]
(dp[j]+sum[j]2−b∗sum[j])−(dp[k]+sum[k]2−b∗sum[k])<=2a∗sum[i](sum[j]−sum[k])
j<k,sum[i]单调增,sum[j]−sum[k]<0
(dp[j]+sum[j]2−b∗sum[j])−(dp[k]+sum[k]2−b∗sum[k])sum[j]−sum[k]>=2a∗sum[i]
我们要最大值,所以队尾保留斜率更大的
const
maxn=1000000;
var
sum,x,y,dp:array[0..maxn]of int64;
t:array[0..maxn]of longint;
i,j,k:longint;
n,l,r,tt:longint;
a,b,c:int64;
function max(a,b:int64):int64;
begin
if a>b then exit(a) else exit(b);
end;
begin
readln(n);
readln(a,b,c);
sum[0]:=0;
for i:=1 to n do
begin
read(x[i]);
sum[i]:=sum[i-1]+x[i];
y[i]:=b+2*a*sum[i];
end;
dp[0]:=0; x[0]:=0;
l:=1; r:=1; t[1]:=0;
for i:=1 to n do
begin
while (l<r)and((x[t[l]]-x[t[l+1]])<(sum[t[l]]-sum[t[l+1]])*y[i]) do inc(l);
tt:=t[l];
dp[i]:=dp[tt]+a*(sum[i]-sum[tt])*(sum[i]-sum[tt])+b*(sum[i]-sum[tt])+c;
x[i]:=dp[i]+a*sum[i]*sum[i];
while (l<r)and(((x[t[r-1]]-x[t[r]])*(sum[t[r]]-sum[i]))<((x[t[r]]-x[i])*(sum[t[r-1]]-sum[t[r]]))) do dec(r);
inc(r); t[r]:=i;
end;
writeln(dp[n]);
end.