1 条题解
-
0
题目理解
我们有一个长度为 的环形字符串,包含字符 J、O、I。我们需要找到一个起始位置,使得从这个位置开始顺时针读取字符串时,得到的字符串是一个K级JOI列,并且修改的字符数最少。
K级JOI列的定义
- 0级:单个字符 J、O 或 I
- k+1级:由4部分组成,每部分长度 :
个 J
个 O
个 I 一个 k级JOI列
例如:
- 1级:JJJJ OOOO IIII + 0级JOI列
- 2级:16个J + 16个O + 16个I + 1级JOI列
解题思路
关键观察
- 环形处理:由于是环形,我们可以枚举所有可能的起始位置( 个)
- 递归结构:K级JOI列有清晰的递归结构,可以递归计算修改成本
- 动态规划:对于每个起始位置,我们可以用DP计算将其变成K级JOI列的最小修改次数
算法设计
对于固定的起始位置,我们可以将字符串分成4个长度为 的部分:
- 第1部分:应该全是 J
- 第2部分:应该全是 O
- 第3部分:应该全是 I
- 第4部分:应该是一个 K-1 级JOI列
递归计算:
- 对于前3部分,修改次数就是该部分中非目标字符的数量
- 对于第4部分,递归计算将其变成K-1级JOI列的最小修改次数
优化:
- 预处理前缀和,快速计算区间内某个字符的数量
- 由于K最大为10,,直接枚举所有起始位置可行
具体实现
- 预处理:计算J、O、I的前缀和数组
- 递归函数:
solve(level, start)计算从start开始长度为 的子串变成level级JOI列的最小修改次数 - 枚举起点:对每个可能的起始位置调用
solve(K, start) - 取最小值:所有起始位置中的最小修改次数就是答案
优化技巧
- 记忆化:可以对solve函数进行记忆化,避免重复计算
- 滑动窗口:利用环形特性,可以只计算第一个起始位置,然后滑动更新
- 并行计算:由于各起始位置独立,可以并行处理
总结
这道题的关键在于:
- 理解JOI列的递归定义
- 将问题分解为递归子问题
- 利用前缀和快速计算修改成本
- 正确处理环形字符串的边界情况
通过递归分解和预处理,我们可以在合理的时间内解决这个问题,即使对于K=10的最大情况。
- 1
信息
- ID
- 5204
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者