决策单调性优化dp

回眸只為那壹抹淺笑 提交于 2020-02-25 22:17:56

概述

决策单调性用于优化一类

  • \(1D1D\)涉及高次,或复杂
  • 二维\(dp\)

具体来说,决策单调性指决策状态与决策点间的单调关系,具象化的证明和运用体现就是四边形不等式

四边形不等式

\(\mathtt{\color{red}Achen}\)说这个东西没有必要因为决策单调性确实有更简便更数学化的证明食用方法,但在实战中,四边形不等式快速辅佐/证伪猜想非常套路

基本概念

首先,定义一维dp决策单调性如下
\(s_i\)表示\(dp_i\)取到的最优决策点\(j\),当\(a<b\)时总有\(s_a\leqslant s_b\)

定义区间单调性如下:
\(a\leqslant b\leqslant c\leqslant d\)时,若\(w\left(b,c\right)\leqslant w\left(a,d\right)\),则称\(w\)满足区间单调性
被包含比包含优

同时定义四边形不等式如下:
\(a\leqslant b\leqslant c\leqslant d\)时,若\(w\)满足如下式子,则称\(w\)满足四边形不等式:
\(w\left(a,c\right)+w\left(b,d\right)\leqslant w\left(b,c\right)+w\left(a,d\right)\)
交错比嵌套优

对一维dp优化

形如\(dp_i=\min\limits_{j=1}^{i-1}\{dp_j+w(j+1,i)\}\)

【定理】当\(w\)函数满足四边形不等式时\(dp\)有决策单调性

也就是说当我们把\(i\)对应的决策表列出时会形如下图

当我们更新完一个状态时之后点的\(s\)可能会发生改变,恰似覆盖颜色

如果一个一个格子去改最坏可以达到\(O(n^2)\),考虑优化

注意到\(s\)值是呈现整块整块的,由于决策单调性,如果一个块会被整体覆盖,那么一定左端点代入更优

因此我们可以用三元组来表示这样一个整块\((l,r,pos)\),\(l,r\)就是左右端点,\(pos\)就是\(s\)数组的值

设计这样一个算法,每次更新状态\(i\),初始快\((i,i,i)\),考虑队列内的块,从块顶开始如果左端点代入更优直接删除,并把新建块的左端点修改,如果不行,二分到最后一个代入不更优的点,并分裂,后半删除,并入新块

对二维dp优化

形如\(dp_{i,j}=\min\limits_{k=0}^{j}\{dp_{i,k-1}+dp_{k,j}+w(i,j)\}\)

【定理】满足以下条件时

  • \(w\)满足区间单调性
  • \(w\)满足四边形不等式

\(dp\)满足四边形不等式

首先令\(s_{i,j}\)\(dp_{i,j}\)的最优决策点然后可以证明\(s_{i,j-1}\leqslant s_{i,j}\leqslant s_{i+1,j}\)

只要特别的顺序枚举,\(s_{}\)的值就能均摊\(O(1)\)的确定

补充

补充一下石子合并这一经典问题解法

对于求最大值,可以证明\(p_{i,j}=i-1\)\(j\)

另外GarsiaWachs算法

步骤如下:

设序列\(\{a_i\}\),从左往右,找一个满足\(a[k-1]\leqslant a[k+1]\)\(k\),找到后合并\(a[k]\)\(a[k-1]\),再从当前位置开始向左找最大的j,使其满足\(a[j] > a[k]+a[k-1]\),插到j的后面就行。一直重复,直到只剩下一堆石子就可以了。在这个过程中,可以假设\(a[-1]\)\(a[n]\)是正无穷的。

举个例子:

\(186\) \(64\) \(35\) \(32\) \(103\)

因为\(35<103\),所以最小的\(k\)\(3\),我们先把\(35\)\(32\)删除,得到他们的和\(67\),并向前寻找一个第一个超过\(67\)的数,把67插入到他后面,得到:\(186\),\(67\),\(64\),\(103\),现在由\(5\)个数变为\(4\)个数了,继续:\(186\),\(131\),\(103\),现在\(k=2\)(别忘了,设\(stone[-1]\)\(stone[n]\)等于正无穷大)\(234\),\(186\),最后得到\(420\)。最后的答案呢?就是各次合并的重量之和,即\(420+234+131+67=852\)

基本思想是通过树的最优性得到一个节点间深度的约束,之后证明操作一次之后的解可以和原来的解一一对应,并保证节点移动之后他所在的深度不会改变。具体实现这个算法需要一点技巧,精髓在于不停快速寻找最小的\(k\),即维护一个“\(2-\)递减序列”朴素的实现的时间复杂度是\(O(n^2)\),但可以用一个平衡树来优化,使得最终复杂度为\(O(n\log_2n)\)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!