7.13 CW 模拟赛 T3. 煮酒论英雄
前言
心态: 冷静, 耐心, 放下
策略
停滞
数据检验, 关键步记录, 简化表述
思路
首先简化问题, 把无用的被包含的字符串去掉
这一步具体的实现方式是拼到一起之后做 \(\rm{KMP}\)
现在如果只有一个字符串, 那么显然答案就是它的最短循环节
如果有多个字符串, 如何做?
考虑最优解的构造, 不难发现环是不好处理的, 我们首先强制最优解中 \(s_1\) 是正着的, 再把环从 \(s_1\) 开头处断开
现在 \(\forall i\), 要么满足整个字符串是 \(s_i\) 的循环节, 要么满足包含 \(s_i\)\((\)包括前后各一段的那种包含\()\)
好的, 现在我们要考虑一种方法, 使其能够遍历可能最优解
第一步是, 去除前后各一段的那种包含, 不难发现我们可以预处理出每个 \(s_i\) 和 \(s_1\) 的前后覆盖, 当这些 \(s_i\) 作为序列结尾时, 可以被 \(s_1\) 覆盖的区域不考虑
不难发现这个串覆盖不完 \(s_1\), 否则是全包含不合法
现在要么满足整个字符串是 \(s_i\) 的循环节, 要么满足包含 \(s_i\)\((\)不包括前后各一段的那种包含\()\)
第二步是去除整个字符串是 \(s_i\) 的循环节的情况
因为现在的字符串已经互不包含了, 因此只要现在还剩 \(3\) 个及以上的字符串, 一定存在一个字符串不能被包含在循环节中
特殊的情况是恰好剩下 \(2\) 个字符串, 此时结尾字符串会被切掉一段, 可能恰好被某个循环节包含
这种情况下我们特殊做一下即可
现在整个序列一定要完整包含若干 \(s_i\) 且开头的顺序 \(s_1\) 确定
我们简单的适用状压 \(\rm{DP}\) 即可
总结
考虑遇到问题先转化, 先简化
最优化问题优先找最优解构造, 本质上是一个不断优化最优解构造方式的过程
本题的关键在于先去掉无用部分, 不然会多出超级多的 \(\textrm{corner case}\) 根本没法想