问题表述
- 有n个无区别的物品,将它们划分为不超过m组,求出划分方法数模M的余数。我们将这种划分记为 n 的 m 划分.
- 这道题是挑战编程竞赛中 dp 专题里面的一道题, 上课的时候看了半天一直没明白为什么状态转移方程的推导是那个样子的. 回到实验室的时候看着别人的文章突然想明白了, 所以在这里记录一下.
解法
- 我们将 dp[i][j] 定义为 j 的 i 划分.
- 对于 n 的 m 划分来说, 其可以划分为{ ai }, 这是一个由 ai 组成的集合, 其中 ∑mi=1ai=n , 然后我们讨论 { ai }的值的分布情况
∀ai∈{ai},ai>0
- 此时, size({ai})=size({ai−1})
- 对此, 我们就有 n 的 m 划分就等价于 n-m 的 m 划分, 即有 dp[m][n] = dp[m][n-m]
∃ai∈{ai},ai=0
- 只要存在一项 ai=0 , 原问题其实就相当于 n 的 m-1 划分, 即 dp[m][n] = dp[m-1][n]
- 这里或许会有人疑问, 为什么不考虑 ai=0 的项大于1的时候, 其实这里也是我上课的时候困惑的地方. 事实上, 多出来的 ai=0 的项已经被包含在 n 的 m-个物品1划分中, 因为所谓的划分就是将 n 划分到不超过 m-1组中.
总结
- 综上, dp 的转移方程为两种可能的相加, 即 dp[m][n] = dp[m-1][n] + dp[m][n-m], 我们就得到原问题的解啦.