【学习笔记】dp
决策单调性优化
感谢一下这篇,真心写得好吧。这部分笔记基本按照上面的东西来写的。
目前只知道应用于形如 \(f_i=\min\{g_j+w(j,i)\}\) 的式子。要求 \(g\) 是常数或者一个满足决策单调性的数组或者 \(f\) 本身,并且 \(w(j,i)\) 满足四边形不等式,则 \(f\) 满足决策单调性。应用决策单调性还需要 \(g\) 和 \(w(j,i)\) 可以较快计算出来保证复杂度。记 \(p_i\) 表示 \(f_i\) 取到最值的 \(j\),若对于任意 \(i<k\) 都有 \(p_i\le p_k\) 则称 \(f\) 满足决策单调性。
一般的证明方法是感性理解(大胆猜测)或者大力把转移点打出来瞪眼观察。因为证明一般很难。
四边形不等式
对于函数 \(f(x,y)\),若其对于任意 \(l_1\le l_2\le r_2\le r_1\) 有 \(f(l_1,r_2)+f(l_2,r_1)\le f(l_1,r_1)+f(l_2,r_2)\),我们称其满足四边形不等式。简记为交叉不大于包含。
分治写法
如果 \(f_i\) 的转移和之前的 \(f\) 值无关(用另一个东西转移,比如说多层 dp 中的上一层)可以考虑把所有 \(f\) 按照一种整体二分的分治思路处理。
具体地定义分治函数 solve(l,r,L,R)
表示现在处理的是 \([l,r]\) 的 dp 值,并且已知这些位置的 \(p\) 值在 \([L,R]\) 范围内。考虑暴力 \(O(R-L)\) 得到 \(dp_{mid}\) 和 \(p_{mid}\) 然后分治左右两块,solve(l,mid-1,L,p[mid])
和 solve(mid+1,r,p[mid],R)
。复杂度是很经典的分治复杂度 \(O(n\log n)\)。但是要保证得到 \(dp_{mid}\) 的复杂度能够接受。
其实大多数情况是能够接受的。你甚至可以用 指针暴力跳区间 在正确的复杂度内得到答案。口胡的证明:可以考虑刻画指针的移动路径。一次分治内左端点从一开始的位置移到 \(L\),然后到 \(R\)。这期间右端点没有变。考虑往左边分治时指针从 \(R\) 移回 \(L\) 进行接下来的行动,然后往右边分治的时候左端点本来就在 \(R\)。所以左端点的移动是 \(O(R-L)\) 的。而往左边分治时右端点只会左移,从左边的分治往右边走时移动次数不会超过 \(R-L\),所以右端点的移动也是 \(O(R-L)\) 的。
斜率优化
目前只知道应用于对前面的一些 dp 值取 max/min 转移时使用。
一种比较通用的是如果 \(i\) 从 \(j\) 转移来的转移式能够化为与 \(i\) 相关的某项和与 \(j\) 相关的某项的乘积加上与 \(j\) 相关的某项再加上与 \(j\) 无关的项,会发现前面三个组成一个形如 \(kx+b\) 的一次函数形式,将与 \(j\) 有关的项当做 \(k,b\),查询 \(x=\) 与 \(i\) 有关的项时的最值。然后套上李超树进行转移。比较典型的例子有(随便举一个)\(dp_i=\min\{a_i\times(dp_j+b_j)+w(j)\}+s\),就可以把 \(dp_j+b_j\) 当做 \(k\),\(w(j)\) 当做 \(b\),然后查询 \(x=a_i\) 时的极值。
感觉适用范围很广,在做过的为数不多的斜率题里面都是可以用李超树优化的。而且板子会背也不难写。