决策单调性优化
数学推导比较多。但是充斥着对称美。
单调队列/斜率优化,都是决策单调性优化。这篇主要说四边形不等式优化。
还没写完。
基本定义
四边形不等式:对于二元函数 \(w_{x,y}\),如果对于定义域内任意 \(a\le b\le c\le d\),都有 \(w_{a,b} + w_{c,d} \ge w_{a, c} + w_{b, d}\)(相交 \(\le\) 包含),那么称 \(w_{i,j}\) 满足四边形不等式。 (定义①)
等价转化
对于二元函数 \(w_{x,y}\),若对于任意 \(a<b\),存在 \(w_{a,b+1} + w_{a+1,b} \ge w_{a,b} + w_{a+1,b+1}\),那么 \(w_{i,j}\) 也满足四边形不等式。(定义②)
定义①通常用来推出某些结论,定义②通常用来证明某个二元函数满足四边形不等式。
证明等价:
对于 \(c > a\),如果 \(c = a + 1\),则有:\(w_{a,c+1} + w_{a+1,c} \ge w_{a,c} + w_{a+1,c+1}\) 成立,否则有:
加起来得到:
以此类推,得到对于任意 \(a\le b\le c\),有:
故技重施。对于 \(c < maxn\),
加起来得到:
以此类推,得到定义①。
矩阵形式
对于 \(N \times M\) 的矩阵 \(A\) 满足四边形不等式:
那么称 \(A\) 是完全单调的。因为
也即,\(A_{*, j}\) 比 \(A_{*, j+1}\) 增长更快,如果第 \(i\) 行最小值在第 \(j\) 列取到,那么对于 \(\forall i_1 > i, j_1 < j\),有 \(A_{i_1, j_1} \le A_{i_1, j}\)。
这就是四边形不等式的本质,相交小于等于还是大于等于包含不重要,只是推出了一个矩阵的单调形式,放弃了很多没用的矩阵。
应用类型 I
考虑如下 dp 转移式子:
其中 \(v\) 满足四边形不等式。
那么:若对于 \(i\),其决策点 \(p\) 比任意 \(k < p\) 都更优,那么对于 \(i'>i\),其决策点 \(p\) 比任意 \(k < p\) 都更优。
证明:
相加得到
不难得到推论,\(p_i\) 单调增。
那么如何求出整个 DP 数组呢?可以从 \(O(n^2)\) 优化到 \(O(n \log n)\)。方法叫做二分栈。
我们考虑 \(p\) 数组,\(p_i\) 表示考虑了目前算到的 DP 值,\(i\) 的最优决策。
一开始,计算出 \(f_0\),然后 \(p\) 数组长这样:\(\mathtt{0000000000}\)
若干个数求完之后,数组可能变成了:\(\mathtt{0000111122}\)
假设已经求完了 \(0 \sim 2\) 的所有 DP 值并放进数组中了,那么显然 \(p_3\) 即为 \(3\) 的最优决策。以此计算 \(f_3\)。
考虑如何添加 \(f_3\) 的贡献。找到一个位置,使得它之后所有数都应该填 \(3\),例如 \(\mathtt{0000113333}\)。这个有可二分性。但是暴力填写不行,复杂度退化为 \(O(n^2)\)。怎么办?
考虑维护颜色段,类似珂朵莉树思想。用一个集合,元素为 \((l,r,k)\),表示一段为 \(k\) 的区间。那么我们从右往左找到分割点所在区间,把右边的段全部删掉即可。已经算完的左边的点也删掉,避免污染。为什么不两层二分?实际上这个复杂度是最对的。因为最多只会有 \(n\) 段加入了,总共也就最多有 \(n\) 段被删除了。这个思想在 KMP 算法的时间复杂度证明中出现过,这里又出现了。
实现方面,用 deque。或者 list。后者,比较安全,但是不能随机访问。(这里不需要随机访问。)
应用类型 II
考虑如下 DP 转移式:
其中 \(v\) 满足四边形不等式。易证对于每个 \(j\),\(dp_{i,j}\) 满足决策单调性。
先介绍另一种方法,然后考虑这两种方法有什么不一样。这种方法叫分治。没错,分治博客里面有一个决策单调性的例题。现在知道了原理。(变成套路了捏)
考虑 \(solve(l,r,x,y)\) 表示计算 \(dp_{l \sim r, j}\) 的值,决策点范围在 \((x,y)\)。考虑计算出 \(mid\) 的决策点 \(k\),然后 \(solve(l, mid - 1, x, k), solve(mid + 1, r, k, y)\)。注意一下边界判断。
考虑时间复杂度。虽然带端点,但是端点计算次数是 \(O(区间数)=O(n)\) 的,所以还是 \(O(n log n)\)。
不同之处
第二种情况,是没有用到左边的 dp 值,直接先算出了右边的 dp 值的。而当遇到第一种情况那样,dp 值后来也是决策的时候,就不管用了。
因此用哪种方法,关键是看 dp 值在这一轮中会不会作为决策。
应用类型 III
考虑如下转移:
若满足以下三个条件:
- \(w\) 满足四边形不等式。
- \(f_{i, i} = w_{i, i} = 0\)。
- \(\forall a \le b \le c \le d, w_{ad} \ge w_{bc}\)(权值的区间包含关系)
那么 \(f\) 也满足四边形不等式。
证明:要证明对于任意 \(i < j\),有 \(f_{i,j+1} + f_{i+1,j} \ge f_{i,j} + f_{i+1,j+1}\)。
首先证明 \(j=i+1\) 的情形。
当 \(j = i + 1\) 的时候,\(f_{i,j+1} + f_{i+1,j} = f_{i, i + 2} + f_{i + 1, i + 1} = f_{i, i + 2}\)。(第二个条件)
右边 \(= f_{i, i + 1} + f_{i + 1, i + 2}\)
考虑 \(f_{i, i + 2}\) 的决策点是 \(i\) 还是 \(i + 1\)。
- 决策点是 \(i\)。
那么 \(f_{i, i + 2} = f_{i, i} + f_{i + 1, i + 2} + w_{i, i + 2} = f_{i + 1, i + 2} + w_{i, i + 2}\);\(f_{i, i + 1} = w_{i, i + 1} \le w_{i, i + 2}\),得证。 - 决策点是 \(i + 1\)。
同法可得证。
然后证明,如果对于 \(j - i < k\) 成立,那么对于 \(j - i = k\) 也成立:
先考虑推得的定义①式子,我们需要使用它。显然,由归纳假设推得的定义①形式为:
做好了准备工作之后,我们考虑证明对于 \(j - i = k\),\(f_{i,j+1} + f_{i+1,j} \ge f_{i,j} + f_{i+1,j+1}\)。
考虑 \(x,y\) 分别为 \(f_{i,j+1},f_{i+1,j}\) 的最优决策点。那么有 \(i \le x \le j, i < y < j\)。
考虑 \(x,y\) 大小关系:
- \(x \le y\),那么 \(i < x \le j, i < y < j\)。
那么 \(y,x\) 也是 \(f_{i,j},f_{i+1,j+1}\) 的一个决策。注意任意一个决策算出来的 \(f\) 值要小于最优决策。于是 \(f_{i,j + 1} + f_{i + 1, j} = f_{i, x} + f_{x +1, j + 1} + w_{i, j + 1} + f_{i +1 , y} + f_{y + 1, j} + w_{i + 1, j}\), \(f_{i,j} + f_{i + 1, j + 1} \le f_{i, x} + f_{x +1, j} + w_{i, j} + f_{i +1 , y} + f_{y + 1, j + 1} + w_{i + 1, j + 1}\)。
由于 \(w\) 满足四边形不等式, \(w_{i,j} + w_{i + 1, j + 1} \le w_{i, j + 1} + w_{i + 1, j}\),那么要证明原式其实也就是证明 \(f_{x + 1, j} + f_{y + 1, j + 1} \le f_{x + 1, j + 1} + f_{y + 1, j}\)。由于 \(x + 1 \le y + 1 \le j < j + 1, j - (x + 1) < k\),这个式子是成立的。 - \(x > y\),同法可证。
因此 \(f\) 满足四边形不等式。
推论:对于任意 \(i < j\) 有,\(p_{i, j - 1} \le p_{i, j} \le p_{i + 1, j}\)。(决策单调性)
证明:考虑右式,设 \(q = p_{i, j}\),那么对于任意 \(i < i + 1 \le k \le p\) 有 \(f_{i, p} + f_{i + 1, k} \ge f_{i, k} + f_{i + 1, p}\)。那么要证明对于 \(f_{i + 1, j}\),\(k\) 比 \(p\) 要劣,也就是 \(f_{i + 1, k} + f_{k + 1, j} + w_{i + 1, j} - f_{i + 1, p} - f_{p + 1, j} - w_{i + 1, j} \ge 0\)。由上面的式子可得。
因此考虑一个矩阵 \(p\),一个格子上的点总是在它左边的点和下面的点中间。例如如下矩阵,标绿色的是参与计算的格子,那么 \(1\) 号格子 $\le $ \(2\) 号格子 \(\le\) \(3\) 号格子。
因此在计算一个点的时候,缩小了枚举范围。事实上,把 \(O(n^3)\) 优化到了 \(O(n^2)\)。为什么呢?考虑格子 \(p_{i, j}\) 的枚举长度为 \(p_{i + 1, j} - p_{i, j - 1} + 1\)。
那么每个格子被上面的格子 \(+1\)(如果有的话),被下面的格子 \(-1\)(如果有的话)。
容易发现,因为 \(p_{i, j} \le n\),总共计算次数是 \(O(n^2)\) 的。