斜率优化

f[i]=min{f[j]+a[i]|j<i}

f[i]=min{f[j]+a[j]|j<i}

f[i]=min{f[j]+a[i]+a[j]|j<i}

像上面这些 i 的信息和 j 的信息不相关的线性DP,用堆,单调栈,线段树等都可以进行优化,但是如果 i 的信息和 j 的信息相关,比如:

f[i]=min{f[j]+(a[i]a[j])2|j<i}

就不能用普通的方法优化了,这时候需要用到斜率优化。


我们考虑上面那个DP(假设 {an} 是递增的),如果对 i 来说 j k 好( k<j<i ),那么:

f[j]+(a[i]a[j])2<f[k]+(a[i]a[k])2

展开移项:

f[j]+a[i]22a[i]a[j]+a[j]2<f[k]+a[i]22a[i]a[k]+a[k]2

f[j]+a[j]2(f[k]+a[k]2)<a[i]×(2a[j]2a[k])

X(i)=2a[i],Y(i)=f[i]+a[i]2 ,则:

Y(j)Y(k)X(j)X(k)<a[i]

然后会发现这货是斜率的形式QwQ。


K(k,j)=Y(j)Y(k)X(j)X(k) ,则 K(k,j)<a[i] i 来说, j k 优秀,同理 K(k,j)>a[i] i 来说, k j 优秀。

接下来还可以推一个结论 K(k,j)K(j,i) j 不会或没必要出现在最优解中,为什么呢?

  1. K(j,i)<a[i] ,那么对 i 来说, i j 优秀,由于 {an} 递增,所以 i 将一直比 j 优秀。

    • K(j,i)a[i] ,那么 K(k,j)K(j,i)a[i] ,即对 i 来说, k j 优秀,由于 {an} 递增,所以 k 将一直比 j 优秀。
    • 所以 m 个候选最优解一定满足 K(que[i1],que[i])<K(que[i],que[i+1])(1<i<m) ,即斜率递增。

      那么用一个单调队列就可以维护了:

      1. K(que[Head],que[Head+1])<a[i] ,则队首失效,删除队首。
      2. 此时队首是最优解,以此算出 f[i]
      3. K(que[Tail1],que[Tail])K(que[Tail],i) ,则队尾失效,删除队尾,加入 i

      相信大家会发现我强调了多次 {an} 递增,实际上并不一定需要递增,如果不递增,斜率优化会更加繁琐 (所以我不会) ,可能需要cdq分治或splay维护。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值