1 条题解

  • 0
    @ 2025-11-11 9:10:14

    题目理解

    我们有一个长度为 4K4^K 的环形字符串,包含字符 J、O、I。我们需要找到一个起始位置,使得从这个位置开始顺时针读取字符串时,得到的字符串是一个K级JOI列,并且修改的字符数最少

    K级JOI列的定义

    • 0级:单个字符 J、O 或 I
    • k+1级:由4部分组成,每部分长度 4k4^k1. 1. 4k4^k 个 J 2. 2. 4k4^k 个 O
      3. 3. 4k4^k 个 I 4. 4. 一个 k级JOI列

    例如:

    • 1级:JJJJ OOOO IIII + 0级JOI列
    • 2级:16个J + 16个O + 16个I + 1级JOI列

    解题思路

    关键观察

    1. 环形处理:由于是环形,我们可以枚举所有可能的起始位置(4K4^K 个)
    2. 递归结构:K级JOI列有清晰的递归结构,可以递归计算修改成本
    3. 动态规划:对于每个起始位置,我们可以用DP计算将其变成K级JOI列的最小修改次数

    算法设计

    对于固定的起始位置,我们可以将字符串分成4个长度为 4K14^{K-1} 的部分:

    • 第1部分:应该全是 J
    • 第2部分:应该全是 O
    • 第3部分:应该全是 I
    • 第4部分:应该是一个 K-1 级JOI列

    递归计算

    • 对于前3部分,修改次数就是该部分中非目标字符的数量
    • 对于第4部分,递归计算将其变成K-1级JOI列的最小修改次数

    优化

    • 预处理前缀和,快速计算区间内某个字符的数量
    • 由于K最大为10,410=10485764^{10} = 1048576,直接枚举所有起始位置可行

    具体实现

    1. 预处理:计算J、O、I的前缀和数组
    2. 递归函数solve(level, start) 计算从start开始长度为 4level4^{level} 的子串变成level级JOI列的最小修改次数
    3. 枚举起点:对每个可能的起始位置调用 solve(K, start)
    4. 取最小值:所有起始位置中的最小修改次数就是答案

    优化技巧

    1. 记忆化:可以对solve函数进行记忆化,避免重复计算
    2. 滑动窗口:利用环形特性,可以只计算第一个起始位置,然后滑动更新
    3. 并行计算:由于各起始位置独立,可以并行处理

    总结

    这道题的关键在于:

    1. 理解JOI列的递归定义
    2. 将问题分解为递归子问题
    3. 利用前缀和快速计算修改成本
    4. 正确处理环形字符串的边界情况

    通过递归分解和预处理,我们可以在合理的时间内解决这个问题,即使对于K=10的最大情况。

    • 1

    #2995. 「JOISC 2015 Day1」愉快的标志设计

    信息

    ID
    5204
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者