ABC221G Jumping Sequences 题解
Jumping Sequences
把移动的上下左右改成左上、左下、右上、右下(坐标轴旋转 \(45\)°)。则最终目的地是 \((A+B,A-B)\)。
(以前移动的方式是 \((\pm d_i,0),(0,\pm d_i)\)。现在每次移动的方式是 \((\pm d_i,\pm d_i)\))
则 \(x,y\) 两维可以分开考虑。
等价问题:从 \(d_1\sim d_n\) 中选若干个数和为 \(w=\frac{A+B-\sum d_i}{2}\)。
DP,\(f[i][j]\) 表示前 \(i\) 个数和为 \(j\) 是否可行。
但是这个复杂度是 \(O(n^2D)\) 的,\(i\) 的范围 \(n\),\(j\) 的范围 \(n\times D.\)(\(D=\max d_i\))
如何优化?
可以 bitset 优化。\(O(\dfrac{n^2d}{32})\)。有点危险。
介绍一种新的方法。\(O(nD)\)。
我们找到一个数 \(b\),\(X=d_1+\dots+d_{b-1}\le w,d_1+\dots+d_b>w\)。
定义 Balanced Set:\(\{1,2,\dots,b-1\}\) 是一个 BS。 所有能通过下列两个操作从 \(\{1,2,\dots,b-1\}\) 变化到达的也是 BS。
-
balanced insert:插入一个 \(\ge b\) 的数。这个操作要求当前的和 \(\le w\)。
-
balanced delete:删除一个 \(<b\) 的数。这个操作要求当前的和 \(>w\)。
观察:所有 BS 的总和 \(\in [w-D,w+D]\)。
观察:最优解也是一个 BS。
为了方便,重新设状态定义,从 \(b\) 处向两边延申。
\(f_{l,r,j}\) 表示考虑 \([l,r]\) 内的操作,是否可以凑出 \(j\)。
初值 \(f_{b+1,b,X}=true.\)
转移:
-
\(f_{l,r,x}\leftarrow f_{l,r-1,x}\;,\;f_{l+1,r,x}.\)(不选)
-
\(f_{l,r,x+d_r}\leftarrow f_{l,r-1,x}.\;(x\le w)\)
-
\(f_{l,r,x-d_l}\leftarrow f_{l+1,r,x}.\;(x>w)\)
但复杂度还是没变。再重新设计。
\(g_{r,w}\) 表示满足 \(f_{l,r,w}=true\) 的 \(l\) 最大是多少。若不存在则为 \(0\)。
-
\(g_{r,x}\leftarrow g_{r-1,x}.\)
-
\(g_{r,x+d_r}\leftarrow g_{r-1,x}.\;(x\le w)\)
-
\(g_{r,x-d_l}\leftarrow l.\;(x>w,l<g_{r,w})\)
从左边转移但不操作 \(l\) 的情况不用考虑,因为 \(g\) 是取 \(\max\)。
状态数少了,但转移复杂度没变。瓶颈在于第三类转移。
注意到 \(l<g_{r-1,x}\) 时,其会在 \(r-1\) 用第一类转移到。所以只要转移 \(l\ge g_{r-1,x}\) 即可。
对于一个 \(x\),转移复杂度为 \(O(\sum g_{r,x}-g_{r-1,w})=O(n)\),所以总复杂度 \(O(nD)\)。