[贪心] [dp] AT_agc022_e [AGC022E] Median Replace
posted on 2025-04-25 02:38:50 | under | source
题意:一个 \(01\) 串假如能通过若干次“将三个连续的数替换为它们的中位数”的操作,最终变成 \(1\),则称它是合法的。将串 \(S\) 中的通配符替换为 \(0/1\) 能得到多少合法串?\(|S|\le 3\times 10^5\)。
考虑合法的条件。肯定要尽量多 \(1\) 而少 \(0\)。可以考虑用一个栈扫一遍,栈中存储剩余元素,我们归纳地认为栈由下面一段 \(1\) 和上面一段 \(0\) 构成:
-
若新增了 \(0\):
- 若栈顶已有 \(2\) 个 \(0\),直接消掉即可。
- 若栈顶只有一个 \(0\) 或者栈为空,先入栈,看看之后怎么决策。
- 若栈顶为 \(1\),你发现操作的数若包含 \(01\),则可以认为是消掉 \(01\) 保留剩下元素。但是之后可能有新来的 \(0\) 发生抵消,所以还是先入栈等待。
-
若新增了 \(1\):
- 若栈顶有 \(0\):此时这些 \(0\) 不可能和后面的 \(0\) 相消,并且先前已经做过决策了,所以可以放心地让 \(01\) 消掉。
- 否则入栈。
显然 \(0\) 的个数 \(\le 2\),同时注意到若左边有 \(\ge 2\) 个 \(1\) 则必胜。那么容易有 dp,\(f_{i,j,k}\) 表示考虑 \([1,i]\),栈中 \(j\) 个 \(1\),\(k\) 个 \(0\)。可以认为 \(j=2\) 的情况为必胜态。
复杂度 \(O(n)\)。

浙公网安备 33010602011771号