用生成函数和复数巧解一道计数题

对集合,求出其中有多少子集,使得子集中的元素和为5的倍数。本文对3Blue3Brown的解法上进行总结,形成较为数学化的语言。本题背后有较为深刻的数学思想,故记载于此。

把原问题转化为生成函数

原题是:对集合,求出其中有多少子集,使得子集中的元素和为5的倍数。

首先容易想到的是,可以采用穷举法,遍历的每个子集,检查是否满足条件。但是,穷举法的复杂度是,这对计算机来说都是一个天文数字。显然,需要另辟蹊径。

不妨先简化一下题目:求出集合中有多少个子集,使元素之和为,我们可以很快地列出这些集合:

换句话说,可以表示为:,如果我们把它表示成一个关于未知数的多项式,那么就有:

什么情况会同时出现呢?答案是生成函数。这启发我们使用下面的生成函数:

这个多项式展开之后的结果是:

注意五次项前面的系数是3,这是因为,有三个来源,分别是,正好对应了之前简化题中的结果!

现在分析一下,多项式中的每个项,都代表了整数,如果在括号中选择了,则表示把这个整数加入集合,如果选择了,则表示不加入。而把整个多项式展开之后的结果,项前面的系数,正好代表了元素之和为的集合的个数!

这时候,我们就能把原问题转化为下面的生成函数:

求出其中所有次数为的倍数的项系数之和:

下面的问题就是如何求出

转化为复数问题

显然,我们不可能把中的每一项都求出来,只能设法一次求出,那么怎么办呢?

我们还是先考虑简化问题,假设现在生成函数是:

如果我们代入,可以求得;如果代入,可以求得;再代入,有。用展开式表示结果:

通过后面两式,不难得到:

我们找到了所有奇数项系数之和,但是我们的目标是所有的倍数的项系数之和。但这个过程可以给我们一个启发:是否可以通过代入某些值到生成函数中,通过加减运算消去我们不关心的项,得到最终的结果

分析我们把代入到中每一项的过程,所有的偶数项结果都是,所有的奇数项结果都是。换句话说:这个值对函数的未知项的循环次数为,或者,每两项代入的结果都相同。同理,对来说,循环次数是

那么,什么时候循环次数是呢?也就是,代入哪个数,会使得,或者。显然,在复空间中,这个数就是。也就是说,如果令,则有个数满足我们的要求,其中就是我们熟知的实根。

更关键的是,这几个数的和是

现在,分别把这五个值代入到展开的生成函数中,有:

注意对应的项,正好都有,把它们加起来,有:

是已知的,所以上面的结果就变成了:

现在整个式子右边只留下常数和的倍数的项!

唯一遗留的问题就是式子左侧的是多少,或者说是多少,因为只要知道了的值也就知道了。

这里的技巧是,因为是方程的五个根,所以可以把它们表示成:

代入:

从而,我们也就有,而。所以,我们就得到了:

这样一来我们考虑的简化版问题就得到了解决!

按照这个思路,我们同样可以得到原始问题的解决,分为几步。

第一步:设是方程的五个根,把它们分别代入生成函数中,相加,就得到:

第二步:把表示为,通过代入解出

第三步:把代入到生成函数中,可以得到,同理有,同时有

第四步:把所有值代回第一步中的结果,得到最终答案

总结

本题背后蕴藏着较为深刻的数学思想,一方面是巧用生成函数把一个计数问题转化为一个分析问题,另一方面是使用复数消去某些项,直接求出想要的结果。通过本题,我们可以充分了解到复数所蕴含的关于周期和频率的思想,从而也就能理解为什么傅里叶变换用复数表征。

把本题稍微进行推广:对集合和正整数,其中。设中满足元素之和为的倍数的子集个数为,你能求出的表达式吗?