母函数入门
问题引入
- 假设我们当前有质量分别为 1g, 2g, 3g, 4g 的砝码各一个, 我们可以构造出多少种质量为7g的砝码方案?
基础解法
- 显然, 想要指定重量的砝码序列的构造, 对于每一个砝码, 我们都有使用或者不使用两种选择. 如果我们对每个砝码进行枚举的话, 则共需要枚举
24
种选择, 即这种解法的时间复杂度为
O(2n)
.
代数解法
- 我们定义变量 x 代表砝码, x 的次幂代表砝码的质量. 例如
x4
就代表当前砝码的质量为 4g. 那么由选择或者不选择当前砝码, 我们可以将其写为表达式 :
(1∗x0+1∗x4)
,
x0
代表我们不选择当前砝码进行构造,
x4
代表我们选择当前砝码进行构造.
- 那么我们就可以将对砝码的序列构造成一序列表达式的乘积, 即
(1+x)(1+x2)(1+x3)(1+x4)
- 我们展开这个表达式, 可以得到
1+x+x2+2x3+2x4+2x5+2x6+2x7+x8+x9+x10
- 由我们的定义可知, 幂函数对应的系数即为构造某个砝码重量的方案数.例如
x7
的系数为 2, 那么我们有两种方案, 即 7 = 1 + 2 + 3 = 3 + 4
母函数定义
- 将一个离散序列对一个幂函数序列对应起来, 构造一个新的离散数列.
- 即给定离散序列
a0,a1,…,an
和 幂函数序列
x0,x1,…,xn
, 我们构造出一个函数:
G(n)=a0x0+⋯+anxn=∑iaixi
- 我们称函数
G(x)
为 序列
a0,a1,…,an
的母函数
联系
问题解决
代码
"""
1. 计算给定最大价值邮票数额, 计算出小于给定价值的邮票的组成方案数的集合.
2. 我们不保存幂函数的次幂, 只保存幂函数的系数. 因为次幂可以通过下标的枚举来控制.
"""
def generating_func(value):
value += 1
count = [1] * value
temp = [0] * value
for expression_index in range(2, value):
for item_index in range(0, value):
for mul_item_index in range(0, value, expression_index):
if item_index + mul_item_index < value:
temp[mul_item_index + item_index] += count[item_index]
count = temp.copy()
temp = [0] * value
return count
其他应用
- 我们对于指定邮票数额的构造可以看做一系列一定数量的一些邮票数额的加法, 反过来看, 那么其也可以对应成整数的拆分, 例如 7 = 1 + 2 + 4. 所以幂函数的系数也可以看做整数的拆分数.
总结
- 本文介绍的方法只适用于母函数的入门, 如果还需要深入学习, 需要点击下面的链接, 有更多的资料可以学习.
参考文献
母函数详解
母函数入门