单调性优化学习笔记

单调性优化辣么多。。不急。。一个个来,先斜率优化

斜率优化

1、简介

\ \ \ \ \ \ \ \ 斜率优化是用来对一类具有决策单调性的动态规划转移方程进行决策优化的方法,主要是通过决策单调性构造出斜率形式,并通过代数方法/几何方法发掘其特征并使用适当的数据结构维护决策。

2、形式

\ \ \ \ \ \ \ \ 形如\(dp[i]\ =\ min/max\{a[i]\ \times\ x[j]\ +\ b[i]\ \times\ y[j]\ +\ c[i]\}\)的状态转移方程,可以考虑使用斜率优化。

3、解题思路(直接法)

\ \ \ \ \ \ \ \ 这里采用直接化式子的方法。还有一种是假设i处决策点j比决策点k更优,得到斜率式子,看斜率的单调性如何,x坐标(分母上的被减数或减数)增减性如何,跟直接法类似。这里只介绍直接法。
\ \ \ \ \ \ \ \ 先将dp方程化为\(dp[i]\ =\ min/max\{a[i]\ \times\ x[j]\ +\ b[i]\ \times\ y[j]\ +\ c[i]\}\),变形后可得\(y[j]\ =\ -\frac{a[i]x[j]}{b[i]}\ +\ \frac{dp[i]c[i]}{b[i]}\),把决策j看作是二维平面上的点,上述式子等价于直线方程y = kx + b,可以看到k一定,我们的目标是最大/最小化b。是不是很像线性规划?我们把(x[j],y[j])看做很多点,用斜率为$-\frac{a[i]}{b[i]}$的直线上下移动,第一个碰到的点使得截距最大/小,实际上就是线性规划找最大/最小值的思路!我们会发现所有最优决策点会形成一个上/下凸壳。接下来的问题就是维护这个上/下凸壳

情况1:决策横坐标x[j]和斜率k单调

\ \ \ \ \ \ \ \ 这意味着我们可以使用单调队列维护。我们这里只考虑k和x[j]都单调递增的情况。我们想象一条直线在一堆点外渐渐往上靠,靠到一个点后斜率增加继续靠.....靠到的这些点形成了一个下凸壳。我们把这些点按照x顺序从小到大排,由于随着斜率增加,碰到的点的横坐标也随之增加,因此碰到点的顺序就是按x从小到大排的这些点的顺序。可是有一些点并不在下凸壳中,该怎么排除这些点呢?设s(i,j)表示点i与点j的斜率,如果有s(i,j) > s(j,k)且i < j < k,那么点j就不会被直线靠到。也就是说,点j不是下凸壳上的点。如此,使用单调队列维护决策点即可。队尾元素相当于j,队尾前一个元素相当于i,当前元素相当于k。

情况2:决策横坐标x[j]单调,斜率k不单调

\ \ \ \ \ \ \ \ 仍旧可以使用单调队列维护上/下凸壳,根据x[j]单调性,在单调队列上二分相邻两点,根据斜率判断区间怎么移动即可。

情况3:决策横坐标[j]与斜率k均不单调

\ \ \ \ \ \ \ \ \ 这意味着不能再用单调队列维护了,我们需要用一个更加高级的数据结构来动态维护下凸壳——平衡树。我们用平衡树维护一个下凸壳,根据x大小建树,每个节点还要存他跟相邻节点的斜率。插入的时候,先根据他的前驱后继与插入点的斜率关系(见前文)来看他是否能加入凸壳,能的话左右不断删点即可。查询转移点的时候,直接沿着splay找即可。什么二分什么的都不用。还可以用CDQ分治,即把状态区间[l,r]分成[l,mid],[mid+1,r]递归求解,然后对[l,mid]递归求解,可以得到其所有的dp,然后考虑用[l,mid]更新[mid+1,r],对[l,mid]按x排序,可以按照上面的斜率思想线性构造凸壳,然后把[mid+1,r]按斜率排序,尺取法即可线性用[l,mid]去更新[mid+1,r],总复杂度O(nlog^2n)。

决策单调性

待填坑

四边形不等式

待填坑

posted @ 2018-02-03 17:09  嘒彼小星  阅读(366)  评论(0编辑  收藏  举报