dp优化瞎吹
dp优化瞎吹
众所周知,我们在dp的转移过程中,可以用一些方法,优化它的转移复杂度。
由于我这边的资料不多,并且例题要么很简单,要么很难,所以我学的脑子有点乱,东西也乱,抱歉啊
前言
对于dp的优化,我个人有些浅显的理解,不知恰当不恰当
我感觉它大概就是,我先写一个dp,再想办法把它变得更快。
怎样更快呢?我可以优化状态数,也可以优化转移。
对于状态数的优化,在dp基础那一篇里有些许提到。而这里主要是针对转移的优化。
转移可以怎么优化呢?我可以 打表 观察转移点的规律,减少转移数;也可以用数据结构,直球的加速转移。
数据结构优化
最直白的一种。这种直接对着转移做就行了。
如果转移是一段 前缀/后缀的和/min/max/积/啥别的, 我们可以使用前缀和优化。这种非常傻逼,例题略。
如果转移是一段区间的min/max/啥别的,还要带修改,那估计得上线段树优化。当然,有一种特殊的:我们的区间长成一段滑动窗口,并且求min/max,我们可以使用单调队列优化,少一个log
然后就是,对于 \(f_i+...\rightarrow f_{i+1}\) 这样的转移,发现它是一个区间平移操作,可以利用平衡树的插入操作支持,因为插入相当于自带一个“让位置”。
以下是例题。
线段树优化:CF833B
很容易写出暴力dp:\(f(k,i)\) 表示分了 \(k\) 段,选到 \(i\) 位置,最大的价值和。
那么 \(f(k,i)=\max\ f(k-1,j)+w(j+1,i)\),\(w(l,r)\) 表示 \([l,r]\) 里面不同种类数。
然后我们发现这个东西可以用pre数组贡献出来:对于 \([j+1,i]\) 中的位置,如果它 \(pre\le j\) ,那就贡献 \(1\)。
枚举 \(k\) ,然后枚举 \(i\)。线段树维护:对于每个 \(j\),当前取 \(j\) 位置转移,权值 \(f(k-1,j)+w(j+1,i)\) 能取到多少。首先用 \(f(k-1,*)\) 作为权值建一颗数,对于每个新来的 \(i\),对于 \((pre_i,i]\) 区间内的 \(j\),可以多一个贡献出来,给它权值 \(+1\) 就行。我们发现它很明显可以线段树维护:区间+1,区间求max。
然后就搞一遍,复杂度 \(O(nk\log n)\)
平衡树优化:CF809D
就拿LIS的那个dp做,发现是一个区间平移的形式,啪的一下打完平衡树,很快啊,哎,就A掉了
另见:这里,这边主要讲的是做dp的思维方法,更加详细一些
决策单调性
对于 \(f_i\),我们要选一个 \(j<i\),使得 \(g(j)+w(j,i)\) 最优化(可能是min/max)。
设 \(p_i\) 表示 \(i\) 这个位置的最优决策点。如果这个 \(p\) 是递增的,这个就叫 决策单调性
如果有这个性质,咋搞呢?我们可以分治,设 calc(l,r,L,R)
表示,要求区间 \([l,r]\) 的dp值,当前的转移位置区间确定在 \([L,R]\) 中。设 \(mid\) 为 \(l,r\) 中点,暴力找到它的最优位置 \(p\),然后由决策单调性递归确定左右两边的转移位置,递归调用 calc(l,mid-1,L,p),calc(mid+1,r,p,R)
即可。复杂度一个 \(\log\)。
除此之外,有些决策单调性的题目也可以在单调栈上二分。不过复杂度一样,并且适用的范围完全被包含了,所以我没有去学,也不太会。
那如何发现这个性质呢?如果足够聪明,你可以脑子里想到几个东西,然后推一推,很快就可以推出来这个性质。如果你不够聪明,像我一样,就可以使用打表,发现这个 \(p\) 好像增。多造点数据,assert一波,发现确实没问题,诶↑,单调性来了。
我们也可以取观摩一下 FlashHu的博客,然后根据函数的交点数/导数等性质,判断它是否满足决策单调性。
以下是例题。
POI2011
LightningUZ Conductor (幻视)
首先转换为 \(p\ge a_j-a_i+\sqrt{|i-j|}\)。那就变成对于每个 \(i\),求 \(j\) 使得后面那一坨最大。把 \(j<i\) 和 \(j>i\) 分开做,最后合并一下即可。现考虑 \(j<i\)
可以用一个dp,\(f(i)=\max\left(a_j+\sqrt{|i-j|}\right)-a_i\)
我们可以用数学方法推式子来证明它的决策单调性,也可以观察打表,发现它的决策单调性。
然后就随便做一波就行了。
CF868F
首先,我们使用理性证明 打表,百度,谷歌 等方法发现了决策单调性。证明详见上面FlashHu的博客。
然后用分治算就行了。
过程中,我们发现,我们需要一个够快的方法来支持区间权值的询问。可以考虑像莫队一样增/减一个位置来移动区间。我们又发现,同一层里面,区间 \(l,r\) 都是递增的,所以区间移动 不会增加 分治决策单调性的复杂度
斜率优化
见 这里
四边形不等式
对于一个区间dp,枚举一个中间断点转移的那种,我们可以观察它的最优转移点取在哪。然后有的时候,我们就会发现一个和决策单调性有点类似的性质。设 \(p(l,r)\) 表示 \(l,r\) 的转移点,那么: \(p(l,r-1)\le p(l,r)\le p(l+1,r)\)。此时我们可以用一个和决策单调性类似的继承转移位置的策略,我们不从 \(l\) 开始,而是直接从以前确定好的 \(p\) 开始,看哪个点最优。容易证明这个复杂度是均摊 \(O(n^2)\) 的。
经典例题如石子合并,可以做到 \(O(n^2)\)。
如果用另一种算法结合平衡树,可以做到 \(O(n\log n)\),我不说是哪个
那么四边形不等式是什么呢?
定义:若二元函数 \(f(x,y)\) 对于 \(l\le l'\le r'\le r\),有:\(f(l,r)+f(l',r')\ge f(l,l')+f(r,r')\),则称 \(f\) 满足 四边形不等式
若有一个dp,形如:\(f(l,r)=w(l,r)+\max\{(l,k)+f(k+1,r)\}\),则以下三个命题等价:
- \(f\) 满足四边形不等式
- \(w\) 满足四边形不等式
- \(f\) 的最优转移位置 \(p\),满足 \(p(l,r-1)\le p(l,r)\le p(l+1,r)\)
证明:我不会,可以感性理解,领悟它的正确性(
更多例题:我不清楚