题解【CF1363F Rotating Substrings】

CF1363F Rotating Substrings *2600
解题报告。
不一定更好的阅读体验

感觉楼上的 DP 状态设计与 DP 转移方程的联系是说不通的,有些地方没有讲明白,所以这篇题解就详细讲一下。

首先,一次操作的本质是,将一个 \(S\) 的一个字符插到前面的某一个位置。

-1 是容易的,即对于任意一个字符 \(c\),在 \(S\) 中的出现次数和 \(T\) 中的出现次数是相等的。

那么我们就可以设 \(f_{i,j}\) 表示将 \(S\) 的长度为 \(i\) 的前缀,插入最少几个字符,使得和 \(T\) 的长度为 \(j\) 的前缀相同。显然这里 \(i,j\) 的大小关系为 \(i\le j\)

考虑 \(f_{i,j}\) 的转移,首先,我们可以不让 \(s\) 的前缀 \(i\)\(t\) 的前缀 \(j\) 匹配,而是让 \(s\) 的前缀 \(i\)\(t\) 的前缀 \((j-1)\) 进行匹配,这时候会多出一个 \(s_j\) 没有匹配。我们让 \(i\) 之后的某一个 \(s_k=t_j\) 的字符 \(s_k\) 向前移动到 \(i\) 的前面,与 \(s_j\) 进行匹配,花费为 \(1\)。注意,这里一定会找到一个合法的 \(s_k\),因为每一个字符都是两两配对的。于是我们有状态转移方程 \(f_{i,j}=f_{i,j-1}+1\)

其次是比较简单的 case,若 \(s_i=t_j\),那么可以通过 \(f_{i-1,j-1}\) 来继承。\(f_{i,j}=f_{i-1,j-1}\)

最后一种情况,设 \(x\) 表示 \(s_i\)\(S\) 的前缀 \(i\) 中出现次数,\(y\) 表示 \(s_i\)\(T\) 的前缀 \(j\) 中出现次数。

\(x\le y\) 说明了什么?考虑 \(f_{i-1,j}\)\(S\) 的前缀 \((i-1)\)\(T\) 的前缀 \(j\)\(s_i\) 的数量 \(x',y\) 一定满足 \(x'<y\)。这也就说明,要想完成 \((i-1)\)\(j\) 的匹配,就必须至少\(s_i\) 移动到前面。然后再移动若干字符。把 \(s_i\) 移动到前面后再插入若干字符本质上是前缀 \(i\)\(j\) 进行匹配,也就是 \(f_{i,j}\) 的值,所以这个部分就直接继承:\(f_{i,j}=f_{i-1,j}\)

\(x,y\) 求法可以用一个 \(\Theta(26n)\) 的前缀和搞定,转移的复杂度是 \(\Theta(n^2)\) 的,总复杂度为 \(\Theta(n^2)\)

代码实现非常简单,不放了,想要的私信我就好。

posted @ 2022-09-28 08:51  UperFicial  阅读(57)  评论(0编辑  收藏  举报