1 条题解
-
0
好的,这是根据你提供的代码编写的题解和算法标签。
题目解法分析
问题重述
给定长度为 的字符串(仅含
M和O)和修改每个字符的代价 ,定义长度为 的“哞叫”为M后跟 个O。要求对于每个 从 到 ,输出至少包含 个不重叠的哞叫子串的最小修改代价。
算法思路
1. 问题转化
- 将原问题转化为在长度为 的序列上选择若干不重叠的长度为 的区间,每个区间需要满足模式
M+ 个O。 - 对于每个可能的区间 ,计算将其修改为合格哞叫的代价 :
- 位置 必须是
M(否则代价 ) - 位置 到 必须是
O(否则分别加上对应代价)
- 位置 必须是
2. 区间选择约束
选择的区间不能重叠,且由于长度为 ,相邻区间至少间隔 个位置。
3. 分治DP解法
代码采用分治+动态规划的方法:
状态设计
对于区间 ,定义状态:
- :在区间内选择 个不重叠区间,且:
- 左边界限制:前 个位置不能作为区间起点()
- 右边界限制:后 个位置不能作为区间终点()
- 这样设计是为了在合并子区间时处理边界约束
分治合并
- 将区间 分成左右两个子区间 和
- 对于所有可能的边界状态 和 ,如果 ,说明左右子区间在中间可以放置一个完整的哞叫区间
- 使用
conv函数合并左右子区间的DP数组
4. 卷积合并
conv函数实际上是在做代价数组的合并:- 先将DP数组转化为差分数组
- 然后归并排序合并
- 再通过前缀和恢复为原数组
- 这实际上是在计算:选择 个区间的最小代价 + 选择 个区间的最小代价 = 选择 个区间的最小代价
5. 基本情况处理
当区间长度 时,直接枚举所有可能的区间选择方案(状态压缩),计算对应的代价。
算法步骤
-
预处理区间代价
- 对每个可能的哞叫起始位置 ,计算 = 将 修改为合格哞叫的代价
-
分治DP求解
- 递归地将整个序列分成小区间
- 小区间直接枚举所有选择方案
- 大区间通过合并左右子区间的DP状态得到
-
状态合并
- 考虑左右子区间边界状态的兼容性
- 使用特殊的“卷积”方法合并代价数组
-
输出答案
- 最终得到 表示整个序列选择 个不重叠哞叫区间的最小代价
- 输出 到 的结果
复杂度分析
- 预处理:
- 分治DP:由于 ,状态数有限,复杂度约为
- 卷积合并:由于区间选择数量有限,合并代价可接受
算法标签
- 分治动态规划
- 区间DP
- 状态压缩
- 代价合并优化
- 不重叠区间选择
这个解法通过巧妙的状态设计和分治策略,解决了在序列上选择多个不重叠模式区间的最小代价问题,是一个典型的最优化+组合问题的综合解法。
- 将原问题转化为在长度为 的序列上选择若干不重叠的长度为 的区间,每个区间需要满足模式
- 1
信息
- ID
- 3610
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者