《浅谈决策单调性动态规划的线性解法》阅读随笔

读下来唯二的感想

  1. 这就是集训队吗 真nb
  2. 这就是集训队吗 写的什么jb

这 latex 就很离谱好吧 一个变量改好几次名字 我都不知道他在干什么

啊对了没实现代码啊 都是找的 std 和最优解 如果侵犯了什么权利请联系我我删掉

本来会以为这篇不像上一篇 会写得少点 但是我想错了 这篇比上一篇还长点
下一篇来点轻松的数据结构换换脑子!敬请期待!

1 引言

我这写点啥?
别人整了点线性解法相关的好活,我也整点。我先说了说这是个啥,又说了说我的法是啥,然后给你拿题讲讲。谢谢我
反正不要钱,多少看一点~

2 决策单调性的定义

对于标准的 1D/1D 转移

\[f_i = \min_{0\le j < i} d_i + w_{i,j} \]

其中 \(d\) 是一个关于 \(f\) 的函数。

若权函数 \(w_{i,j}\) 满足 \(\forall i, j, \ w_{i,j} + w_{i + 1, j + 1} \le w_{i,j+1} + w_{i+1,j}\),则称 \(w\) 满足凸完全单调性。易证明 \(\forall k > 0, \ w_{i, j + k} - w_{i,j}\)\(i\) 单调不降,\(\forall k > 0, \ w_{i + k, j} - w_{i,j}\)\(j\) 单调不降。则对于 \(\forall 1\le a\le b\le c\le d\le n,\ w_{a,c} + w_{b,d} \le w_{a,d} + w_{b,c}\),我们称该转移具有决策单调性。也就是说,当 \(w_{a,c} \ge w_{b,c}\) 时,我们能得到 \(w_{a,d} \ge w_{b,d}\),也就是说对于 \(i<j\) 的转移点 \(p_i,p_j\) 恒有 \(p_i\le p_j\)

当前位置移动,转移点跟着单向移动,这就是决策单调性。

发现决策单调性的方法是直接观察或者打表 冲一个做法然后过样例 证明四边形不等式(

3 利用斜率优化

可以在线性时间内解决部分转移斜率递增的决策单调性问题。如果转移斜率不递增,只能保留所有决策点形成的凸包,在其上二分求得答案。
转移斜率递增的问题有复杂度 \(O(n)\),反之有复杂度 \(O(n\log n)\)

例题 1:ARC066D

首先考虑无修改时的情况。我们设 \(s_i = \sum_{j=1}^iT_j,\ w_{i,j} = \frac{1}2 (j-i)(j-i-1) - s_j + s_i\)。我们列出方程

\[f_i = \max\{f_{i-1}, \max_{j=0}^{i-1}(f_{j} + w_{j,i})\} \]

前半部分比较平凡。后半部分可以考虑四边形不等式,\(w_{a,c} + w_{b,d} - w_{a,d} - w_{b,c} = ac\times bd - ad\times bc \ge 0\)。若对于 \(k < i\)\(f_{k} + w_{k,j} > f_i + w_{i,j}\)\(k\) 将永远比 \(i\) 优。
利用性质解决问题,下方展开。

3.1 通用解法

考虑对所有的决策维护一个双端队列。加入决策时退队尾直到队尾可能成为最优决策,随后清空队头尾的更劣决策。
查询时二分即可。

3.2 斜率比较

\(A_i = f_i+ \frac{i^2} 2 +s_i\),则对一个决策点 \(j\)\(k<i<j\)\(f_i + w_{i,j} > f_k + w_{k,j}\) 当且仅当 \(\frac{A_i - A_k}{i - k} \ge j - \frac 12\)。论文里这段的式子比较的奇妙,所以我又推了一下,和论文里有点不一样。
然后用栈维护一个斜率递减的上凸壳,不合法的斜率就退栈,退完二分即可。复杂度 \(O(n\log n)\)

进一步的,我们维护一个指向目前最优决策点的指针。当该决策点被退栈时,将指针移动至新的栈顶位置。询问时只需要退指针至第一个斜率不超过决策点的位置即可。移动次数 \(O(n)\),因此总时间复杂度 \(O(n)\)

随后考虑修改。修改单点考虑将决策按照是否覆盖该点分类。
对于不覆盖修改点的方案可以前后计算两次答案后得到。
对于覆盖修改点的方案可以将询问离线,随后在序列上分治。

一段区间内的答案可以由左端点的前缀和、右端点的后缀和以及段内值拼出。前后缀和信息退化,考虑段内值如何求。现在分治区间为 \([l,r]\),中点为 \(mid\)。我们对每个 \([mid+1,r]\) 内的右端点用决策单调性预处理出跨过中点的分数,随后后缀和即可转移。左端点在将序列翻转后同样方法处理即可。

总时间复杂度 \(O(n\log n)\)

但是这个法子不是万能的。来道例题:

4 一个简单的例子

例题 2 [NAIPC2016]Jewel Thief
\(n\) 个物品,每个物品有重量 \(w_i\) 和价值 \(v_i\)。现在要对于 \(V\in [1,K]\),求出体积为 \(V\) 的背包能装下的最大值。\(1\le n \le 10^6,\ 1\le K \le 10^5,\ 1\le w_i \le 300, \ 1\le v_i \le 10^9\)

不是很简单,不会。这段贺了。

首先在选同种物品的时候肯定是先选价值大的。
\(f_{i,j}\) 为选了前 \(i\) 种体积的物品,总体积为 \(j\) 的最大价值。我们将模 \(i\) 同余的所有位置(啥位置啊)拿出来重新编号,则有

\[f_{i,j} = \max_{k=0}^j \left\{ f_{i-1,k} + w_{k,j} \right\} \]

其中 \(w_{k,j}\) 为体积为 \(i\) 的物品中前 \(j-k\) 大的物品的价值和。注意到 \(w_{k,i}\) 的值只与其长度有关,且增量随长度增加减小。四边形不等式的满足表示两边长度之和相同时较为平均的一边和最大,容易证明 \(w\) 满足四边形不等式。

同时该转移满足:每个点在决策时不依赖原先的决策,不需要按照顺序依次决策。

4.1 问题转化

转化完会了
upd: 转化完更看不懂了

对于矩阵 \(A\),令 \(A_{i,j}\) 描述矩阵的第 \(i\) 行第 \(j\) 列的元素,\(A_i\) 描述矩阵的第 \(i\) 行的元素,\(A^j\) 描述矩阵的第 \(j\) 列的元素,\(A[i_1,\cdots,i_n : j_1,\cdots,j_m](i_k < i_{k+1}, j_k < j_{k+1})\) 描述矩阵第 \(i_1,\cdots,i_n\) 行与 \(j_1,\cdots,j_m\) 的交组成的 \(n\times m\) 子矩阵。

\(pos(k) = \text{argmax }A_{i,k}\)。具体地说,第 \(k\) 列最大值里最右边的那个的位置。

原问题可以只考虑一层的转移。因此令 \(A_{i,j} = f_{i} + w_{i,j}\)。当 \(i > j\) 时,\(A_{i,j} = -\infty\)。转化成新问题:
已知一个 \((K+1)\times (K+1)\) 大小的矩阵,其中每个元素的值都能 \(O(1)\) 查询。现在要求出所有 \(A_{pos(j), j}\)

4.2 一种简单的分治法

确实挺简单(

原问题满足 \(\forall\ 0\le i < j \le K, \ pos(i) \le pos(j)\)。因此可以对列分治,维护一个当前 \([l,r]\) 的候选行 \([x,y]\)。每次取出 \([l,r]\) 的中点 \(mid\),暴力扫出 \(pos(mid)\) 的位置。随后只需要递归 \((mid, pos(mid))\) 点左上和右下的子矩形即可。
\(T(n,m)\) 为解 \(n\times m\) 的矩形的复杂度,则

\[T(n,m) \le m + \max_{1\le j\le m}\left\{T(\left\lceil\frac n2\right\rceil - 1, j) + T(\left\lfloor\frac n2\right\rfloor, j)\right\} \]

容易发现 \(T = O(K\log K)\)

4.3 \(\text{SMAWK}\) 算法

正主来了。

在上面的分析里少了一个词:四边形不等式。所以我们还没有完全挖掘出这类问题的性质。

定义一下单调矩阵。一个矩阵是单调矩阵,当且仅当 \(\forall 0\le i < j \le K, \ pos(i)\le pos(j)\)。这表明 \(pos\) 单调向左下分布。一个矩阵是完全单调矩阵,当且仅当其任意子矩阵都是单调矩阵。
如果 \(pos(j) \neq i\),则称 \(A_{i,j}\) 为无用元素。

然后引理:一个矩阵为完全单调矩阵,当且仅当其所有 \(2\times 2\) 子矩阵都是单调矩阵。
证明不难,考虑拓展一列的方法,并讨论边界,使用归纳法得证。

有时候行数会大于列数,很多时候都会。所以是不是能够通过合理的预处理将一部分没用的行删除呢?

一个新的问题:
给出一个 \(M\times N\) 的完全单调矩阵 \(A\),支持对每个位置的快速访问。要求出一个 \(N\) 大小的行集合 \(S\),满足 \(\forall i, \ pos(i) \in S\)

引理:设 \(A\) 是完全单调矩阵。若对于 \(i_1 < i_2\),有 \(A_{i_1, j} > A_{i_2,j}\),则 \(\forall 1\le k\le j,\ A_{i_2, k}\) 是无用元素。若对于 \(i_1 < i_2\),有 \(A_{i_1, j} \le A_{i_2,j}\),则 \(\forall j\le k\le N,\ A_{i_1, k}\) 是无用元素。

\(\text{SMAWK}\) 算法中,我们采用 \(\text{Reduce()}\) 函数来解决问题。

伪代码:

\[\begin{aligned} & \textbf{procedure }\text {Reduce(A)}\textbf{ :} \\ & \qquad S\leftarrow \{1, 2,\cdots,M\},\ p\leftarrow 1; \\ & \qquad \textbf{while }|S| > N\textbf{ do:} \\ & \qquad \qquad \textbf{if } A_{S_p, p} > A_{S_{p+1}, p} \text{ and } p < N\textbf{ :} \\ & \qquad \qquad \qquad p\leftarrow p + 1; \\ & \qquad \qquad \textbf{else :} \\ & \qquad \qquad \qquad \textbf{if } A_{S_p, p} > A_{S_{p+1}, p} \text{ and } p = N\textbf{ :} \\ & \qquad \qquad \qquad \qquad \text{Delete}(S_{p+1}); \\ & \qquad \qquad \qquad \textbf{else :} \\ & \qquad \qquad \qquad \qquad \text{Delete}(S_{p}); \\ & \qquad \qquad \qquad\textbf{end if} \\ & \qquad \qquad\textbf{end if} \\ & \qquad \textbf{end while} \\ & \textbf{end procedure.} \end{aligned}\]

正确性没什么问题。在每一轮循环中我们假设 \(S_p\) 就是第 \(p\) 列取到极值的位置,所有后面的都是备选决策位置。然后只需要顺次比较 \(S_p\)\(S_{p+1}\),确定 \(S_p\) 是否能够成为备选决策中的最大位置。

然后很容易证明这玩意的复杂度是 \(O(N+ M)\) 的。

可以解决新的问题了。但如果还是将行列同等均分,那复杂度仍然是 \(O(n\log n)\)
可以每次先 \(\text{Reduce}\),将奇数位拿出来接着递归,再通过决策单调性推出偶数位的答案。
\(a\times b(a <b)\) 的矩阵需要 \(T(a,b)\) 的复杂度计算,则有 \(T(a,b) = T(a/2,a) + O(a + b)\)

带回原问题,可以得到一种 \(O(K)\) 的解法。

5 更常见的问题

考虑需要按照顺序依次决策的 dp 怎么来。

例题 3 U285 数据分块鸡
\(f_{i}\) 为以 \(i\) 作为分界点的情况下,\([1,i)\) 段的最小值。只要设 \(w_{i,j}\)\([i,j)\) 段作为整块的情况下所有询问对该块做出的贡献,就可以得到和例题 1 完全相同的 dp 式。现在证明 \(w\) 有凸完全单调性。

讨论询问 \([l_k, r_k]\)。满足 \(l_k \le i\)\(j + 1 \le r_k\) 的询问都是 \(1\) 的贡献,没差。满足 \(i + 1\le l_k\)\(r_k \le j\) 的询问贡献也没差。
然后讨论 \(l_k \le i\) 的情况。我们设 \(p_{i,j}\) 为块 \([i,j)\) 内改变最优选取方案的位置。考虑移动块,我们有 \(p_{i,j} \le p_{i+1,j} = p_{i, j + 1} \le p_{i+1,j+1}\)
随后分类讨论即可。
\(p_{i+1,j} \le r_k \le p_{i+1,j+1}\) 为例。这时有 \(w_{i,j} = w_{i+1,j}, w_{i+1,j+1} = r_k - (i + 1) \le j + 1 - r_k = w_{i,j+1}\),因此有 \(w_{i,j} + w_{i+1,j+1} \le w_{i+1,j} + w_{i,j+1}\)。其余几种情况同理。
\(j + 1\le r_k\) 时同理,不展开。
证毕。

分类讨论后可以在单次 \(O(\log n)\) 的复杂度内主席树维护 \(w_{i,j}\) 的查询。这部分不展开。

5.1 单调栈

可以直接套一个单调栈上二分上去,不展开。总时间复杂度 \(O(n\log^2 n)\)
同时这也是 std 做法。

Submission

5.2 线性做法

转化。

我们维护两个指针 \(r,c\),初值 \(r = 0, c = 1\)。任何时刻有 \(\forall\ 0\le i < c, \ i\) 的决策已知。

定义序列 \(E_j = A_{x,j},\ x < r\),其取值满足 \(\forall \ j, A_{pos(j), j} = \min\left\{ E_j, \min_{r \le i} A_{i,j} \right\}\);也就是说 \(E\) 保存着目前已知的所有最大值出现位置。我们在下面的做法中将动态维护 \(E\)

\(A[l\sim r]\) 的意义为序列 \(A\) 的子区间 \([l,r]\) 组成的序列。

每一次操作中,我们需要拓展 \(r,c\),并维护 \(E\)

我们设 \(p = \min(2c - r, n)\)。将 \(E[c\sim p]\) 作为新一行放到 \(A[r, r+1, \cdots, c-1 : c, c+1, \cdots, p]\) 的前面,得到一个 \((c-r+1)\times (c-r+1)\) 大小的矩阵。通过归纳法可以得到如此产生的矩阵是一个完全单调矩阵。

注意到这个矩阵每个点的值都是已知的,所以可以运行 \(\text{SMAWK}\) 算法。我们可以在 \(O(c + r)\) 的复杂度内求得该矩阵每列内的最小值。记得到的序列为 \(G\)。注意到
\(G(c) = pos(c)\)。我们倒着求出每个位置的 \(pos(j)\)

引理:当求解 \(pos(k)\) 时,\(A[c, c+1, \cdots, j-2 : j, j +1, \cdots, p]\) 均为无用元素。
如下的决策过程通过归纳法证明了引理。

根据引理,答案定取在 \(G_k\) 所在点与 \(j-1\) 中。
如果 \(A_{j-1,j} < G_j\),则 \(f_j = A_{j-1,j}\),因为此时所有 $ < j-1$ 的决策在 \(j\) 后都不会优于 \(j-1\)。我们取 \(r = j - 1\)\(c = j + 1\) 即可结束该次决策。由于已知决策不优,我们也不需要维护 \(E\)
反之 \(f_j = G_j\)。为维护 \(E\),我们接着比较 \(A_{j-1,p}\)\(G_p\) 的值。
如果 \(A_{j-1,p} < G_p\),根据引理,对于列 \(k\in [j+1,p]\),能够成为 \(pos(k)\) 且位置在 \(j-1\) 前的位置只能在 \(G\) 中出现。我们让 \(r = j-1, c = j+1\)\(E[j + 1\sim p] = G[j + 1\sim p]\)。根据引理,不需要更新其他部分。
反之,\(pos(j)\)\(pos(p)\) 都不可能是 \(j-1\)。这说明了 \(A_{j-1,j}, A_{j-1,j+1},\cdots, A_{j-1,p}\) 都是无用元素。同时由于在接下来 \(j\) 增长的过程中 \(\forall \ j < k \le p, \ A_{c,k}, A_{c+1,k}, \cdots, A_{k-2,k}\) 都会被淘汰,引理得证。
\(j \ge p\)(原文写的大于,但看实现似乎原文炸了),\(f_c\)\(f_p\) 的值都已确定。\(r = pos(p), c=p+1\) 即可。

在单次决策中,我们花费了 \(O(c-r)\) 的时间。若当前情况是 \(j>p\)\(c\) 至少增加了 \((p + 1) - c \ge c - r + 1\);反之 \(r\) 至少增加了 \((j - 1) - r \ge c - r + 1\)\(r,c\) 的上界都是 \(n\),我们总共会移动 \(O(\log n)\) 次指针。因此该做法的复杂度为 \(O(n \log n)\)

Submission

没找到论文作者亲自实现的代码,但从 5.2.2 里能看到他确实实现了。有找到的可以评论区发一下!

6 总结

初等维护法就做到了线性!(
由于 \(\text{SMAWK}\) 算法需要优秀的询问矩阵值的做法作为基础,作者试验了一下询问值的次数。当然咱这做法最稳了,在 \(n=10^6\) 时是表现优秀时的其余做法的 \(\frac 12\)
当函数变化比较平缓时,决策单调性需要的决策点会很少,此时分治法与二分法的询问次数较少,有时在随机数据下能做到期望线性。但当函数比较陡峭时,二分法的询问次数就是 \(O(n\log n)\) 的。第二种情况的例题有 [NOI2009] 诗人小G
应当依据题目选择更合适的算法来做题。

posted @ 2022-11-28 18:20  joke3579  阅读(193)  评论(3编辑  收藏  举报