发现本身傻傻分不清斜率优化和决策单调性→_→,被一些博客误导了。。因而总结一下。萌新们能够先写写[hnoi2008]玩具装箱,并不难。html
相信有心想学习斜率优化的同志们必定本身摸索着写过[hnoi2008]玩具装箱这道题吧,我刚开始学习斜率优化的时候,也是写了这个,而后似懂非懂的发现,好像斜率优化就是先证实决策单调性,而后再用单调队列维护一下什么的,这不就是套个模板的东西吗→_→。函数
对于某一类型的dp方程$${f[i]=Min(a[i]*b[j]+c[j]+d[i])}$$学习
其中$a[x],b[x],c[x],d[x]$是关于$x$的函数,且$b$单增。$——————【1】$优化
按照一向的套路,先数学概括法证实决策单调性。spa
1.概括假设:.net
假设有${i}$前两个决策点${j,k(j<k)}$,且${k}$的决策要比${j}$好,即:指针
$${a[i]*b[j]+c[j]+d[i]>=a[i]*b[k]+c[k]+d[i],j<k——————【2】}$$htm
2.概括推理:blog
此时后面有状态${i+1}$,这里咱们为了简单起见,不妨设${a[i+1]=a[i]-v,v>0}$,也就是${a}$单调递减。$${即证:a[i+1]*b[j]+c[j]+d[i+1] >= a[i+1]*b[k]+c[k]+d[i+1]}$$队列
$${(a[i]-v)*b[j]+c[j]+d[i+1] >= (a[i]-v)*b[k]+c[k]+d[i+1]}$$
$${化简得:a[i]*b[j]+v*b[k]+c[j] >= a[i]*b[k]+v*b[j]+c[k]}$$
$${~}$$
$${由【2】得:a[i]*b[j]+c[j] >= a[i]*b[k]+c[k]}$$
$${由【1】得:b[k]>b[j]}$$
$${又\because v>0}$$
$${\therefore v*b[k] >= v*b[j]}$$
$${得证}$$
因此,决策单调性是存在的。咱们将由决策单调性得出的式子展开,化成斜率式:
$${a[i]*b[j]+c[j]+d[i]>=a[i]*b[k]+c[k]+d[i],j<k}$$
$${-a[i]>=\frac{c[k]-c[j]}{b[k]-b[j]}}$$
记斜率$${slope(i,j)=\frac{c[k]-c[j]}{b[k]-b[j]}}$$
而后发现这个东西很符合单调队列的尿性:
问题就这样优化到了${O(n)}$。
回顾一下咱们之因此可使用斜率优化,是由于这个dp方程具备决策单调性;不然咱们推不出斜率式。以后咱们将决策单调性的式子变形为斜率式,当知足斜率式的时候就代表前一个决策不如后一个决策优,一切都是围绕着决策单调性开展的,能够说决策单调性是斜率优化的前提。(那是真的么,欲知后事,请看下文)
如今咱们换一个角度来考虑问题,刚刚是直接从”数“的角度进行了严谨的证实,那么咱们如今从”形“的角度来意会。
dp方程:$${f[i]=Min(a[i]*b[j]+c[j]+d[i]),b[j]单增}$$
咱们这里沿用上面“数”的条件:${a}$单减,${b}$单增。
移项:$${-a[i]*b[j]+f[i]=c[j]+d[i]}$$
是否是很像直线的斜截式:${-a[i]}$为直线的斜率;直线过点:${(b[j],c[j]+d[i])}$;${f[i]}$即为直线在Y轴上的截距。
能够看出,由于${f[i]}$要尽量小,因此咱们把以前小于${i}$的${j}$画在平面直角坐标系上,一如线性规划,把这条斜线自下往上平移时遇到的第一个点,即能使目前状态有最小值的点。因而咱们须要维护一个下凸壳,把那些确定不会贡献的点删掉。
咱们用一个单调队列维护这个凸壳,由于要保证凸壳的下凸性,因此咱们显然能够获得单调队列pop队尾的条件:${slope(q[r-1],q[r])>slope(q[r],i)}$。
考虑什么状况下pop队首元素(这里咱们的讨论都是基于${f[i]}$取最小值的状况下的):
不错,你必定已经发现第一种状况所对应的维护方式不是跟以前所说“数”的单调队列维护方式如出一辙吗,没错,其实这只是两种不一样的解题方式所得出来的一样的结果。
两种方法各有优缺点吧,“形”的角度比较方便理解,对于更高深的cdq分治维护凸包能够比较清晰的了解。可是遇到复杂的dp方程以及决策单调性证实就得靠“数”了(好比国王饮水记),看状况使用吧。
以前说的决策单调性是斜率优化的基础这句话其实并不严谨,像这种从图形角度来求解的斜率优化就并无用到决策单调性。想想若是能证实决策单调性,那么必定就是对${a}$和${b}$的单调性有要求的,不然的话就是什么斜率不单调啦,在凸包上二分啦什么的。
这就是斜率优化啦。
回顾以前斜率优化的运用,它必需要有一个前提条件:${b}$(横坐标)单增。而若是${b[j]}$不单调怎么办呢?还能不能用斜率优化呢?
答案是能够的,咱们须要使用CDQ分治或者splay来解决这个问题。
斜率单调暴力移指针
斜率不单调二分找答案
x坐标单调开单调队列
x坐标不单调开平衡树|cdq分治
参考资料:
http://blog.sina.com.cn/s/blog_7a1746820100xztv.html