这篇文章主要介绍各种类型的决策单调性优化dp
考虑如下形式的dp
d p i = m i n { d p j + w ( j + 1 , i ) } j < i dp_i=min\{dp_j+w(j+1,i)\}_{j < i} dpi=min{dpj+w(j+1,i)}j<i
也可以是 m a x max max ,这里只讨论 m i n min min 的情况
对于最一般的情况,可以直接 O ( ? ) O(?) O(?) 计算 w ( i , j ) w(i,j) w(i,j) 或从 w ( i , j ) w(i,j) w(i,j) 转移到 w ( i , j + 1 ) w(i,j+1) w(i,j+1) ,可以 O ( ? n 2 ) O(?n^2) O(?n2) 进行转移
如果要更优的时间复杂度,可以进行以下优化
决策单调性优化dp,一般需要满足的形式,对于两个位置 i 1 , i 2 i_1,i_2 i1,i2 有两个决策点 x 1 , x 2 x_1,x_2 x1,x2,如果 i 1 < i 2 i_1<i_2 i1<i2 则 x 1 ≤ x 2 x_1 \le x_2 x1≤x2
如何证明?
{ d p x 1 + w ( x 1 + 1 , i 1 ) ≤ d p x 2 + w ( x 2 + 1 , i 1 ) d p x 2 + w ( x 2 + 1 , i 2 ) ≤ d p x 1 + w ( x 1 + 1 , i 2 ) \begin{cases} dp_{x_1}+w(x_1+1,i_1) \le dp_{x_2}+w(x_2+1,i_1)\\ dp_{x_2}+w(x_2+1,i_2) \le dp_{x_1}+w(x_1+1,i_2) \end{cases} {dpx1+w(x1+1,i1)≤dpx2+w(x2+1,i1)dpx2+w(x2+1,i2)≤dpx1+w(x1+1,i2)
w ( x 1 + 1 , i 1 ) − w ( x 1 + 1 , i 2 ) ≤ w ( x 2 + 1 , i 1 ) − w ( x 2 + 1 , i 2 ) w(x_1+1,i_1)-w(x_1+1,i_2) \le w(x_2+1,i_1)-w(x_2+1,i_2) w(x1+1,i1)−w(x1+1,i2)≤w(x2+1,i1)−w(x2+1,i2)
w ( x 1 + 1 , i 1 ) + w ( x 2 + 1 , i 2 ) ≤ w ( x 2 + 1 , i 1 ) + w ( x 1 + 1 , i 2 ) w(x_1+1,i_1)+w(x_2+1,i_2) \le w(x_2+1,i_1)+w(x_1+1,i_2) w(x1+1,i1)+w(x2+1,i2)≤w(x2+1,i1)+w(x1+1,i2)
只需证明上述不等式即可
回到决策单调性优化,最简单的一种情况,当 x x x 为 i i i 的最优决策点时 d p y + w ( y + 1 , i ) ≥ d p x + w ( x + 1 , i ) dp_y+w(y+1,i) \ge dp_x+w(x+1,i) dpy+w(y+1,i)≥dpx+w(x+1,i) ,这时候只需要用一个指针维护最优决策点 x x x,一但发现决策点 x + 1 x+1 x+1 不会更劣就右移指针
大多数情况没有这么简单,一般要用一个单调栈/队列维护所有有效的决策点,对于一个决策点 x x x ,令 f x ( i ) = d p x + w ( x + 1 , i ) f_x(i)=dp_x+w(x+1,i) fx(i)=dpx+w(x+1,i) ,转移时就是找到最小的 f x ( i ) f_x(i) fx(i) ,依次枚举考虑 i i i 的过程中 i i i 是单调递增的,如果 ∀ j ≥ i f x ( j ) ≤ f y ( j ) \forall_{j \ge i} f_x(j) \le f_y(j) ∀j≥ifx(j)≤fy(j) , y y y 这个决策点就没有任何存在的价值了,可以被移除单调栈/队列
分两种情况讨论
第一种情况,对于两个决策点 x ≤ y x \le y x≤y , 存在一个中心点 m i d x , y mid_{x,y} midx,y 满足
{ ∀ j ≤ m i d x , y f x ( j ) < f y ( j ) ∀ j > m i d x , y f x ( j ) ≥ f y ( j ) \begin{cases} \forall_{j \le mid_{x,y}}f_x(j) < f_y(j)\\ \forall_{j > mid_{x,y}}f_x(j) \ge f_y(j) \end{cases} {∀j≤midx,yfx(j)<fy(j)∀j>midx,yfx(j)≥fy(j)
也就是说决策点 x x x 在 m i d mid mid 及之前是更优的,之后就完全被 y y y 取代了
在单调队列中找 i i i 的最优决策点
考虑单调队列的队首决策点 x x x 和次队首决策点 y y y ,如果发现 m i d x , y ≥ i mid_{x,y} \ge i midx,y≥i , x x x 就被移除队首
移除结束后发现队首决策点 x x x 就是 i i i 的最优决策点
把决策点 i i i 加入队列中时次队尾决策点 x x x ,队尾决策点 y y y ,如果 m i d y , i ≤ m i d x , y mid_{y,i} \le mid_{x,y} midy,i≤midx,y , y y y 就被移除队尾
移除结束后把 i i i 加入队尾
第二种情况
{ ∀ j ≤ m i d x , y f y ( j ) < f x ( j ) ∀ j > m i d x , y f y ( j ) ≥ f x ( j ) \begin{cases} \forall_{j \le mid_{x,y}}f_y(j) < f_x(j)\\ \forall_{j > mid_{x,y}}f_y(j) \ge f_x(j) \end{cases} {∀j≤midx,yfy(j)<fx(j)∀j>midx,yfy(j)≥fx(j)
y y y 在 m i d x , y mid_{x,y} midx,y 之后被 x x x 取代
栈顶决策点 y y y 和次栈顶决策点 x x x ,如果 m i d x , y ≥ i mid_{x,y} \ge i midx,y≥i , y y y 就被移除栈
栈顶决策点 x x x 即为 i i i 的最优决策点
栈顶决策点 y y y 和次栈顶决策点 x x x ,如果 m i d x , y ≤ m i d y , i mid_{x,y} \le mid_{y,i} midx,y≤midy,i , y y y 就被移除栈,最后把 i i i 加入栈顶
现在的问题在于如何找到 m i d x , y mid_{x,y} midx,y
对于大多数的问题,可以二分一个 m i d mid mid 在 log \log log 时间复杂度内完成
但也有一部分问题 w ( i , j ) w(i,j) w(i,j) 是难以直接计算的,只能从 w ( i , j − 1 ) w(i,j-1) w(i,j−1) 推出来
此时如果满足 d p i dp_i dpi 和 d p j dp_j dpj 互不干涉,就可以二分考虑的点 i i i ,暴力找出 i i i 的最优决策点 x x x ,此时小于 i i i 的位置决策点小于等于 x x x ,大于等于 i i i 的位置决点大于等于 x x x ,这样一直递归下去即可
一般对于分层dp,从上一层的状态转移到当前层的状态满足互不干涉的性质,要求互不干涉的原因是可以在计算 i i i 之前的dp值前可以先计算出 d p i dp_i dpi
递归的时间复杂度是 O ( n log n ) O(n \log{n}) O(nlogn) 的
更复杂的情况
d p i = m i n { d p j + A j B i + C j + D i } j < i dp_i = min\{dp_j+A_jB_i+C_j+D_i\}_{j < i} dpi=min{dpj+AjBi+Cj+Di}j<i
其中 A j , C j A_j,C_j Aj,Cj 只和 j j j 有关, B i , D i B_i,D_i Bi,Di 之和 i i i 有关
这时可以考虑斜率优化
转换为
d p j + C j = B i A j + D i − d p i dp_j+C_j=B_iA_j+D_i-dp_i dpj+Cj=BiAj+Di−dpi
形如
y = k x + b y=kx+b y=kx+b
每一个决策点 j j j 就对于平面上一个点 ( x , y ) = ( B i , d p j + C j ) (x,y)=(B_i,dp_j+C_j) (x,y)=(Bi,dpj+Cj)
B i B_i Bi 就是给定一个直线的斜率
现在要求这条给定斜率的直线穿过给定点,交 y y y 轴于点 b b b ,这时 d p i = D i − b dp_i=D_i-b dpi=Di−b
要 d p i dp_i dpi 尽可能小只需要找到最小的 b b b 即可
根据不同题目的各个参数是否具备单调性 , 只需要以不同方式维护这些决策点 (一般是凸包) 即可解决