1 条题解
-
0
「PA 2018 Final」Podobieństwo genetyczne 题解
核心思路
1. 问题转化
我们需要计算长度为 的 DNA 序列 的数量,其中 要么同时是 和 的子序列,要么同时不是两者的子序列。
设:
- = 所有长度为 的 DNA 序列总数 =
- = 是 子序列的序列集合
- = 是 子序列的序列集合
根据容斥原理:
$$\text{答案} = |A \cap B| + |\overline{A} \cap \overline{B}| = |A \cap B| + (U - |A \cup B|) $$由容斥原理:
所以:
$$\text{答案} = |A \cap B| + U - (|A| + |B| - |A \cap B|) = U - |A| - |B| + 2|A \cap B| $$2. 关键观察
问题转化为计算:
- = 中长度为 的不同子序列数量
- = 中长度为 的不同子序列数量
- = 同时是 和 子序列的长度为 的不同序列数量
3. 动态规划解法
由于 ,我们可以使用状态压缩 DP。
定义 表示在 中,处理到位置 时,当前子序列状态为 的方案数。
但更高效的方法是使用子序列自动机的思想。
4. 子序列自动机预处理
对于每个字符串 ,预处理 表示从位置 开始,字符 下一次出现的位置。
5. DP 状态设计
设 表示在字符串 中,从位置 开始可以形成的长度为 的不同子序列数量。
转移:
$$f_s[pos] = \sum_{c \in \{\text{A,C,G,T}\}} f_s[next[pos][c] + 1] $$6. 同时子序列计数
对于两个字符串,定义 表示在 中从 开始,在 中从 开始,能形成的公共子序列数量。
转移:
$$dp[pos1][pos2] = \sum_{c} dp[next1[pos1][c] + 1][next2[pos2][c] + 1] $$7. 记忆化搜索优化
由于 较小,可以使用记忆化搜索,状态为 ,表示还需要选择 个字符,当前在 的 位置和 的 位置。
算法实现
复杂度分析
- 预处理:
- DP计算: 但通过记忆化优化
- 实际运行:由于 ,状态数可控
关键优化
- next数组预处理:快速找到下一个字符位置
- 记忆化搜索:避免重复计算
- 状态哈希:压缩状态空间
- 1
信息
- ID
- 4710
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者