1 条题解
-
0
题解:石柱高度序列还原与动态规划计数
问题分析
本题要求统计满足特定条件的初始高度方案数。关键约束如下:
- 初始有 根石柱,高度为
- 经过 次地震,每次地震中:
- 对于每个高度 ,保护编号最大的高度为 的石柱
- 未被保护的石柱高度减 (高度为 则不再变化)
- 最终剩下的 根石柱编号已知
- 求初始高度分配方案数
关键观察与转化
1. 逆序处理
从最终状态倒推出初始状态更方便。我们考虑从最终剩下的石柱出发,逆向模拟地震过程。
2. 高度变化的性质
设最终留下的石柱集合为 。逆向思考:
- 每次地震(逆过程)相当于将某些高度为 的石柱恢复为
- 随着逆向步骤进行,石柱高度逐渐增加
3. 保护机制的逆向解读
正向过程中,对于每个高度 ,保护的是同高度中编号最大的石柱。逆向后:
- 如果一根石柱在某个高度没有被保护,那么它的高度会减少(正向)或增加(逆向)
动态规划设计
设 表示处理到第 根最终存活的石柱时,有 根石柱的高度已经确定(或已经处理过某些特定操作)的方案数。
实际代码中使用了一维数组 进行优化,其中 表示某种状态下的计数。
状态转移
对于每个新加入的最终存活石柱(编号 ):
- 它本身必须最终存活,因此它在逆向过程中必须一直被保护
- 考虑它"影响"的其他石柱
设当前处理的石柱编号为 (按输入顺序处理), 是已处理的最终存活石柱数量。
状态转移分两部分:
第一部分:处理受保护的石柱 对于已有状态 ,更新为:
这表示:在 个已确定高度的石柱中,有 种方式选择哪些石柱在当前步骤中被"保护"。
第二部分:新增高度组的石柱 对于每个 ,我们可以新增一组高度为某值的石柱(共 对,即 根石柱):
$$f[y+z] \leftarrow f[y+z] + f[y] \times \text{fac}[z] \times C[a-x-y][z] $$其中:
- $\text{fac}[z] = (2z-1)!! = 1\times 3\times 5\times\dots\times(2z-1)$,表示 对高度相同的石柱的配对方案数
- 从可用的位置中选择 对石柱的放置位置
算法步骤
-
预处理:
- 组合数
- 双阶乘
-
动态规划:
- 初始状态:
- 对每个输入的石柱编号 :
- 逆序枚举 (从大到小)
- 先执行第一部分转移
- 然后对每个 执行第二部分转移
-
输出结果:
- 最终 即为答案
正确性证明
- 一一对应:该DP建立了最终存活石柱集合与初始高度分配之间的双射关系
- 保护机制编码: 因子正确编码了保护选择方案
- 高度配对: 正确计算了高度相同的石柱对的排列方式
- 位置选择:组合数正确选择了新增石柱对的位置
复杂度分析
- 时间复杂度:
- 外层循环 次
- 内层对每个 和 进行转移,最坏
- 空间复杂度:(组合数表)+ (DP数组)
对于 是可行的。
总结
本题是一道组合计数与动态规划相结合的优秀题目,主要考察:
- 逆向思维:从最终状态倒推初始状态,简化问题
- 组合建模:将复杂的保护机制转化为可计算的组合系数
- DP状态设计:巧妙设计状态表示石柱的处理进度
- 优化技巧:使用一维数组和逆序枚举避免后效性
算法的核心在于将地震保护过程转化为组合选择问题,并通过DP逐步构建完整的方案。通过预处理关键组合数值,实现了高效计算。
这种"从结果出发,逆向构建"的思路在许多计数问题中非常有效,是解决此类问题的经典范式。
- 1
信息
- ID
- 5809
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者