1 条题解
-
0
这道题是一个经典的 区间 DP 问题,并且因为合并规则的特殊性,需要一些状态设计的技巧。
题目分析
我们有一个长度为 的 01 串,每次合并相邻的 个字符,得到一个新字符和分数,最终合并到只剩 1 个字符,求最大分数。
关键点
- 合并规则:给出所有 种可能的 位二进制串对应的新字符和分数。
- 合并过程:每次合并 个字符 → 1 个字符,长度减少 。
- 最终长度必须为 1,所以 必须为 0。
思路与状态设计
直接设 表示区间 的最大分数不够,因为不知道合并成什么字符,以及中间状态可能不是单个字符。
巧妙的状态设计:
设 表示将区间 合并成一个 二进制状态 的最大分数,其中 的长度为 (如果模为 0,则长度为 )。解释:
- 区间长度 。
- 每次合并减少 长度,所以最终合并成的“临时串”长度 = ,如果为 0 则长度为 。
- 因此 是一个 的整数,表示当前区间合并成的二进制串的值。
- 当 时, 只能是 0 或 1,表示最终合并成的单个字符。
状态转移
对于区间 ,我们枚举一个分割点 ,将区间分成 和 。
设左区间状态为 ,右区间状态为 ,那么合并后的状态是 ,其中 是右区间状态的长度(即 ,如果为 0 则 )。
如果合并后的状态长度等于 (即 ),那么我们可以进行一次合并,得到新字符 和分数 ,更新 。
算法步骤
- 读入 和初始串。
- 读入 种合并规则,存到数组 和 ,其中 是 位二进制数。
- 初始化 DP:对于每个位置 ,,其中 是 。
- 按区间长度从小到大进行 DP:
- 枚举区间
- 枚举分割点
- 枚举左区间状态 和右区间状态
- 计算合并后的状态
- 如果 ,则可以进行最终合并:
- 新字符
- 新分数
- 更新 $dp[l][r][c] = \max(dp[l][r][c], dp[l][m][x] + dp[m+1][r][y] + sc)$
- 否则,如果 ,则不能合并成单个字符,只能作为中间状态:
- 更新 $dp[l][r][comb] = \max(dp[l][r][comb], dp[l][m][x] + dp[m+1][r][y])$
- 最终答案在 和 中取最大值。
复杂度分析
- 状态数:
- 转移:
- 总复杂度:,在 时可行。
总结
这道题的关键在于:
- 发现合并过程长度减少 的规律。
- 设计状态 表示合并成的二进制串。
- 在转移时判断能否进行最终合并。
- 1
信息
- ID
- 3619
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者