CF2091G 题解

CF2091G 题解

时间复杂度分析,bfs

看到这题的第一想法是抽象成图论模型:用三元组 \((pos, x, d)\) 代表在位置 \(pos\),体力值为 \(x\),方向为 \(d\) 的状态。可以用 bfs 跑最短路,状态数为 \(O(sk)\)。实际上的时间复杂度比状态数更高,因为可能多次尝试转移到同一个状态。

我们需要优化这个做法,因为 \(s\) 太大了。合理的猜测是很多状态是无用的,我们可以尝试减少状态数量。

\(k | s\) 时,答案取到最优值 \(k\),否则答案最优为 \(k - 2\)。我们先以 \(k\) 的步长前进若干次,再以 \(k - 1\) 的步长后退若干次,如果能找到某个位置,到终点的距离是 \(k - 2\) 的倍数,那么答案就可以取到 \(k - 2\)。根据直觉,当 \(s\) 很大的时候,我们就有更多的自由控制前进和后退的步数,从而找到一个到终点距离能被 \(k - 2\) 整除的位置,所以答案不劣于 \(k - 2\)

具体而言,一开始我们以 \(k\) 的步长前进到无法前进为止。设 \(r\) 是我们所在位置到终点的距离模 \(k - 2\) 的余数,每往回以 \(k - 1\) 的步长走一次,都会让 \(r\) 在模 \(k - 2\) 的意义下增加 \(1\)。一开始 \(r\) 最小为 \(0\),所以后退至多 \(k - 2\) 次就会使 \(r\) 变为 \(0\),此时再掉头就可以一直到达终点。(注意,由于不能连续掉头,即使一开始 \(r = 0\) 也要往回走。)最坏情况下需要 \(k - 2 + (k - 2)(k - 1) = k(k - 2) < k^{2}\) 的长度,因此只要当 \(s \ge k^{2}\),答案就一定是 \(k - 2\)\(k\)

这个结论的正确性还和出发的位置无关:当 \(s \ge k^{2}\) 时,从 \([0, s)\) 中的任何一个位置出发,答案都不劣于 \(k - 2\)

知道这个结论之后,我们就可以只在 \(s < k^{2}\) 时 bfs。此时时间复杂度最坏为 \(O(k^{3})\),似乎还是过不去,但实际上已经可以过了。继续分析:设答案为 \(x\),我们其实只需 bfs \(k - x\) 次,时间复杂度为 \(O(s(k - x))\)。根据之前得到的结论,如果当前体力值不超过 \(\sqrt{s}\) 且方向向右,就可以在两次掉头内到达终点,所以 \(x \ge \sqrt{s} - 3\)。(不是 \(\sqrt{s} - 2\),因为要考虑方向,但这不重要)因此时间复杂度最坏为 \(O(s(k - \sqrt{s}))\)

我们用均值不等式来求出 \(T = s(k - \sqrt{s})\) 的上界。把 \(T\) 改写成

\[T = \sqrt{s} \cdot \sqrt{s} \cdot (k - \sqrt{s}) = \dfrac{\sqrt{s} \cdot \sqrt{s} \cdot (2k - 2\sqrt{s})}{2} \]

分子中三项的和为 \(2k\),根据均值不等式有

\[T = \dfrac{1}{2} \cdot (\sqrt{s} \cdot \sqrt{s} \cdot (2k - 2\sqrt{s})) \le \dfrac{1}{2} \cdot \left( \dfrac{2k}{3} \right)^{3} = \dfrac{4k^{3}}{27} \]

因此,虽然算法的状态数最多是 \(O(k^{3})\),但常数很小,可以通过。AC 记录

posted @ 2025-03-27 15:47  DengStar  阅读(19)  评论(0)    收藏  举报