1 条题解

  • 0
    @ 2025-10-20 21:17:44

    好的,这是根据你提供的代码编写的题解和算法标签。


    题目解法分析

    问题重述

    给定长度为 NN 的字符串(仅含 MO)和修改每个字符的代价 cic_i,定义长度为 LL 的“哞叫”为 M 后跟 L1L-1O。要求对于每个 kk11N/L\lfloor N/L \rfloor,输出至少包含 kk 个不重叠的哞叫子串的最小修改代价。


    算法思路

    1. 问题转化

    • 将原问题转化为在长度为 NN 的序列上选择若干不重叠的长度为 LL 的区间,每个区间需要满足模式 M + (L1)(L-1)O
    • 对于每个可能的区间 [i,i+L1][i, i+L-1],计算将其修改为合格哞叫的代价 a[i]a[i]
      • 位置 ii 必须是 M(否则代价 cic_i
      • 位置 i+1i+1i+L1i+L-1 必须是 O(否则分别加上对应代价)

    2. 区间选择约束

    选择的区间不能重叠,且由于长度为 LL,相邻区间至少间隔 LL 个位置。

    3. 分治DP解法

    代码采用分治+动态规划的方法:

    状态设计

    对于区间 [l,r][l, r],定义状态:

    • res[i][j][t]res[i][j][t]:在区间内选择 tt 个不重叠区间,且:
      • 左边界限制:前 ii 个位置不能作为区间起点(0i<L0 \le i < L
      • 右边界限制:后 jj 个位置不能作为区间终点(0j<L0 \le j < L
    • 这样设计是为了在合并子区间时处理边界约束

    分治合并

    • 将区间 [l,r][l, r] 分成左右两个子区间 [l,mid][l, mid][mid+1,r][mid+1, r]
    • 对于所有可能的边界状态 (p,i)(p, i)(j,q)(j, q),如果 i+j+1Li + j + 1 \ge L,说明左右子区间在中间可以放置一个完整的哞叫区间
    • 使用 conv 函数合并左右子区间的DP数组

    4. 卷积合并

    conv 函数实际上是在做代价数组的合并

    • 先将DP数组转化为差分数组
    • 然后归并排序合并
    • 再通过前缀和恢复为原数组
    • 这实际上是在计算:选择 xx 个区间的最小代价 + 选择 yy 个区间的最小代价 = 选择 x+yx+y 个区间的最小代价

    5. 基本情况处理

    当区间长度 6\le 6 时,直接枚举所有可能的区间选择方案(状态压缩),计算对应的代价。


    算法步骤

    1. 预处理区间代价

      • 对每个可能的哞叫起始位置 ii,计算 a[i]a[i] = 将 [i,i+L1][i, i+L-1] 修改为合格哞叫的代价
    2. 分治DP求解

      • 递归地将整个序列分成小区间
      • 小区间直接枚举所有选择方案
      • 大区间通过合并左右子区间的DP状态得到
    3. 状态合并

      • 考虑左右子区间边界状态的兼容性
      • 使用特殊的“卷积”方法合并代价数组
    4. 输出答案

      • 最终得到 f[0][0][k]f[0][0][k] 表示整个序列选择 kk 个不重叠哞叫区间的最小代价
      • 输出 k=1k = 1N/L\lfloor N/L \rfloor 的结果

    复杂度分析

    • 预处理:O(N)O(N)
    • 分治DP:由于 L3L \le 3,状态数有限,复杂度约为 O(NlogN)O(N \log N)
    • 卷积合并:由于区间选择数量有限,合并代价可接受

    算法标签

    • 分治动态规划
    • 区间DP
    • 状态压缩
    • 代价合并优化
    • 不重叠区间选择

    这个解法通过巧妙的状态设计和分治策略,解决了在序列上选择多个不重叠模式区间的最小代价问题,是一个典型的最优化+组合问题的综合解法。

    • 1

    信息

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