AGC022

https://atcoder.jp/contests/agc022/tasks


E - Median Replace

先考虑如何判断合法性。显然可以贪心的把 \(000\) 删去两个 \(0\),然后删去剩下的相邻的 \(01\),看最后是否剩下 \(1\),第二步可以看作比较剩下的 \(0,1\) 个数

尝试构建成一个 DFA。使用栈维护前面剩下的 \(0,1\),考虑转移:

  • 添加 \(0\)
    • 栈顶为 \(0\):如果栈顶有两个 \(0\) 那么 pop,否则 push(0)
    • 栈顶为 \(1\):直接 push(0)
  • 添加 \(1\)
    • 栈顶为 \(0\):此时栈顶的这一段 \(0\) 不可能再形成 \(000\),可以直接按 \(01\) 删除,即 pop
    • 栈顶为 \(1\):直接 push(1)

通过转移可以看出:任意时刻栈中从底到顶一定是一段 \(1\) 一段 \(0\),且 \(0\) 的个数 \(<3\)。由于最后剩下的 \(1\)\(0\) 多就合法,栈底的 \(1\) 只需要保存 \(\le3\) 个,且二元组 \((1\text{的个数},0\text{的个数})\) 就能唯一确定 DFA 上状态

最终 DFA 的状态数为 \(12\),时间复杂度 \(O(n)\)。大力手玩可以进一步减小 DFA 状态数

posted @ 2022-08-15 08:30  401rk8  阅读(241)  评论(0编辑  收藏  举报