[模拟赛] String

题目描述:

有两个小写字母串 \(a\)​​ 和 \(b\)​​。老虎不喜欢这两个串,于是认为是任意一个串的子序列的串是坏的。例如若 \(a=xyz\)​,\(b=xtq\)​,那么 \(x\)\(xz\)​ 和 \(xq\)​ 是坏的, \(xx\)​ 不是坏的。

解题思路:

首先要解决一个问题,假设你有一个字符串你需要判断这个字符串是否是坏的,怎么快速判断?

我们预处理出 nxta[i][j] 表示 \(a\) 字符串中第 \(i\) 个位置之后第一个 \(j\) 字符出现的位置。

\(b\) 字符串同理。

我们判断时只需要扫一遍当前的字符串,并用 nxt 数组在 \(a\), \(b\) 上跳,如果都跳出去了,那么就是好串,反之坏串。

那么怎么算最短的这个串呢?

考虑 \(\text{dp}\)

f[i][j] 表示最短的最后一位等于 \(a[i]\), \(b[j]\),的字符串长度。

假设当前字符串 \(a\) 枚举到位置 \(i\)\(b\) 枚举到位置 \(j\),第 \(i + 1\) 位填 \(x\),转移式子: f[nxt][i + 1][x]][nxt[j + 1][x]] = f[i][j]。最后我们要的答案就是 f[n + 1][m + 1]

但是这个很对的做法,时间复杂度是 \(O(26 \times n^2)\),只能获得 \(80\) 的高分。

\(100\) 分也很简单啊,直接将答案和第 \(2\) 位交换一下,注意到答案不会超过 \(\frac{n}{26}\)

那么我们的转移式子要改变一下,假设当前字符串 \(a\) 枚举到位置 \(i\),答案字符串长度为 \(j\), 下一位 \(x\)

f[nxt[i + 1][x]][j + 1] = max{nxt[f[i][x] + 1][x]}。最后只要判断 f[i][j] >= m+1 是否成立即可。

posted @ 2024-10-04 18:47  _huangweiliang  阅读(30)  评论(0)    收藏  举报