斜率优化——apio2010特别行动队

这是我写的第二个斜率优化。。。

有了更深的认识

发现斜率优化很神奇,加一个斜率和单调队列就可以了

发现是斜率优化重点是找到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.


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值