这是我写的第二个斜率优化。。。
有了更深的认识
发现斜率优化很神奇,加一个斜率和单调队列就可以了
发现是斜率优化重点是找到f[i]=min(max){f[j]+w[j,k]}这样一个DP方程,然后试着对决策j优于k列式子讨论,作数学变形。发现有一边是dp[]之差比定值[j] [k]之差就是斜率。
还有要注意斜率可以用slop算出来,这样程序更清晰,条件也比较好看
program tt;
var i,n,a,b,c,xx,l,r:longint;
f:array[0..1000000]of int64;
s:array[0..1000000]of int64;
q:array[0..1000000]of longint;
function slop(x,y:longint):double;
begin
slop:=(f[x]-f[y]+a*s[x]*s[x]-a*s[y]*s[y]+b*s[y]-b*s[x])/(2*a*(s[x]-s[y]));
end;
begin
read(n);
read(a,b,c);
s[0]:=0;
for i:=1 to n do
begin
read(xx);
s[i]:=s[i-1]+xx;
end;
l:=1;r:=1;q[1]:=0;f[0]:=0;
for i:=1 to n do
begin
while (l<r) and (slop(q[l],q[l+1])<s[i]) do l:=l+1;
f[i]:=f[q[l]]+a*sqr(s[i]-s[q[l]])+b*(s[i]-s[q[l]])+c;
while (l<r) and (slop(q[r],i)<slop(q[r-1],q[r])) do
r:=r-1;
r:=r+1;
q[r]:=i;
end;
writeln(f[n]);
end.