动态规划的斜率优化

如题,动态规划的斜率优化

给出如下一个状态转移方程:

  f[i]=max{x[j]*x[i]-2*f[j]}

  (我们假设x[i]单调增——她也许就是一个正整数列的前缀和)

我们需要一种基于该转移的快速求解f[i]的方法

观察发现:

f[i]的取值与x[j],x[i],f[j]有关;

由于,对于一个f[i],x[i]的取值已然却定;

于是答案的大小取决于x[j]与f[j],换言之,取决于对j的决策对答案的贡献;

  (这不废话么)

一个挺好的想法是枚举j,找出max;

  (慢得要死了)

一个挺好的想法是将f[i]看为函数值;

一个空空如也的坐标系

一个空空如也的坐标系

那么x[j],x[i],f[j]三项中得有一个为自变量;

。。。。。。。。。。。。

(博主企图解释为什么取x[i]为自变量,然后放弃了)

总之取x[i]为自变量,可以把式子化为直线方程;

看出 :

k:x[j];

b:-2*f[j];

于是,f[i]看做x=x[i]时的函数值;

于是我们画出f[i]=x[j]*x[i]-2*f[j]在不取MAX的可能的情况(因为j的不唯一,而存在多条直线)

关注竖线与斜线的交点

竖线表现x[i]的取值;

于是观察下函数:

f[i]=max{x[j]*x[i]-2*f[j]}

(多了个max)

当我们的j有很多选项时;

意味着有很多直线存在;

但max的存在意味着我们的函数只看处于最上面的一段直线

咦,半平面交哟

黄线看做函数的真正图像;

恩,一个半平面交,但先不考虑这个;

由于,x[]单增;

即k,和自变量单增;

所以直线们本来就是按越来越邪的顺序加入队列的

由于x[i]的递增,对f[i]贡献的线也理应越来越邪(即x小时,k小的线还能占点b的优势,随x的增加,b的优势就消失了)
于是维护单调队列,当队首这个斜率的直线不如下一条优时,她就失去意义了,该出队了,因为之后的x[]只会越来越大,她与大斜率之间的差距只会越来越大。

于是取现在的队首信息构成f[i]的答案

还有一点注意的;

即,队尾的出队操作;

我们需要用队尾的出队操作维护一个半平面交;

方法是如果队尾前1个位置的直线与要加入队列的直线的交点在队尾直线之上,则队尾出队,重复多次直至不符合条件;

为什么维护平面交?

可以看出,当出现上图、也是上文中提到的情况时;

紫线连函数的一部分都不是,当然贡献不了答案了

换言之,维护半平面交即是维护函数图像的过程;

(也可以说函数图像具有半平面交的性质)

 这个性质的作用:

对,这是上文的句子;

但她本身有些欠考量;

这句话成立的前提条件,是维护了半平面交;也就是使上图中的紫线不在队列里;

不然紫线会因为自己的弱小,衬托出要选小斜率直线的假象;

友情提示:加黑字体(不含本句)即是具体要做的操作;

原文地址:https://www.cnblogs.com/nietzsche-oier/p/6613636.html