一个挺妙的 DP 题(
两个结论:
第一,满足对于 2≤i≤k,si−1 是 si 的后缀的一个答案一定是最优解之一。
证明:若不满足,则将 si 中,si−1 第一次出现的位置删去,下一步的决策显然不会变少,即答案不会变劣。
第二,在 Parent Tree 上,某个祖先的所有字符串在这个状态的所有字符串的匹配情况相同。
证明就不写了,这个用 endpos 等价类的性质不难证明。
那么就有方案了:在 Parent Tree 上,从根向下 DP,每个状态向上找最近的一个在当前链最优解中的状态,看其是否能在该状态内匹配两次(即除了作为后缀还有另一次,这个可以通过线段树合并维护 endpos 来维护)。
如果可以就加入最优解,否则直接跳过,这个状态便是对答案无用的。
然而往上找的过程,如果倍增的话需要 O(nlog2n)。
虽然也能过,但是实际上直接在 DP 过程中即可维护这个需要的状态。
O(nlogn) 即可。
代码:
1 |
|