小球装箱问题
小球装箱问题:有k个球,装进n个箱子里,问有几种方案?分别讨论球是否相同,箱子是否相同,每个箱子至少一个、至多一个、没有限制,共12种不同情况。
第一种:球不同,箱子不同,没有限制
我们对球讨论,每个球都独立地有n种选择。只要有一个球的选择不一样,结果就不一样。因此共有nk种方案。
第二种:球不同,箱子不同,每个箱子至多一个球。
这首先要求箱子要比球多。那么先选出哪些箱子里有球,有(kn)=k!(n−k)!n!种选法。球可以全排列,有k!种排法。因此共有(n−k)!n!。这正好是n的k阶下降阶乘幂,记作(n)k。
第三种:球相同,箱子不同,每个箱子至多一个球。
箱子比球多。只需要选出k个有球的箱子就好了,答案是(kn)。
第四种:球相同,箱子不同,每个箱子至少一个球。
插入n−1块隔板,隔板的位置有k−1个可选,答案是(n−1k−1)。
第五种:球相同,箱子不同,没有限制。
要插n−1块隔板,但箱子可以为空。我们选择在k+n−1个元素中挑出n−1个变成隔板,所以答案是(n−1k+n−1)。这是从箱子的角度来考虑的。如果从球的角度考虑,那么每个球选择了一个箱子,但球是没有区别的,所以所有k个球的选择构成的是一个元素可以重复集合(与顺序无关),称为“可重集”。所以我们知道了,总共k个元素且每个元素的范围在1到n的可重集个数为(n−1k+n−1),记为((nk))。等价于从n个元素里选k次,每次选的可以是重复的,选完的结果是不考虑顺序的。
第六种:球不同,箱子相同,每个箱子至少一个球。
箱子相同,所以装箱等价于分组。把k个不同元素分成n组的方案数,我们把这个数记为{kn},称为第二类斯特林数(the second type of Stirling number)。我们将在下一节证明求解第二类斯特林数的递推公式,在“容斥原理”一文中证明第二类斯特林数的通项公式。
第七种:球不同,箱子不同,每个箱子至少一个球。
在第二类斯特林数{kn}的基础上,现在箱子不同了,原来的每种分组方案都可以对应箱子的全排列。所以答案是{kn}⋅n!。
第八种:球不同,箱子相同,没有限制。
没有限制说明分的组数可以大到n组,小到1组。答案是i=1∑n{ki}。
第九种:球相同,箱子相同,每个箱子至少一个球。
相当于要把一个数字k分解成n个数字的和。这个答案称为划分数,记为P(k,n)。我们将在下一节证明求解划分数的递推公式。
第十种:球相同,箱子相同,没有限制。
划分的个数可以从1到n,答案为i=1∑nP(k,i)。
第十一种:球不同,箱子相同,每个箱子至多一个球。
如果球的个数比箱子少,那么每个球自成一组,只有这一种方案。如果球的个数比箱子多,那么一定不可能有解。答案是1[k≤n]。
第十二种:球相同,箱子相同,每个箱子至多一个球。
同上,答案是1[k≤n]。
用组合意义证明恒等式
在组合数学中有一种称为double counting的证明恒等式的方法:如果数同一个东西有两种不同的数法,那么两种数法的表达式对应的结果必然相等。
恒等式1
杨辉三角:
(kn)=(k−1n−1)+(kn−1)
证明:等式左边表示从n个不同的元素里选k个。也可以这么讨论:讨论第n个元素有没有被选。如果被选了,那么对应的方案数等价于从前n−1个里选剩下的k−1个;如果没有被选,那么对应的方案数等价于从n−1个里面选k个。所以等式两边只是同一个问题的两种不同看法而已。
恒等式2
((nk))=((nk−1))+((n−1k))
等式左边表示从n个不同的元素里可重复地选k个,选的结果是忽略顺序的。也可以这么讨论:讨论第n个元素有没有被选。如果被选了,那么它可以继承所有从n个里选k−1次的结果;如果没有被选,那么只能继承所有从n−1个元素里面选k次的方案了。
恒等式3
范德蒙德卷积(Vandermonde convolution):
j=0∑k(mj)(nk−j)=(m+nk)
这个式子说明,从m+n个元素里选k个,可以分类讨论从前m个里选j个,从后n个里选k−j个。
恒等式4
{nk}={n−1k−1}+k⋅{n−1k}
把n个元素分成k组。如果第n个元素自成一组,那么继承n−1个元素分k−1组的方案;如果第n个元素没有自成一组,那么它所在的组至少有两个元素。那么前n−1个元素必须已经分成了k组,第n个元素必须加入其中一组。注意这样是不会重复的,因为加入这个元素后发生重复说明加入前就已经重复了,与“不同的方案数”矛盾。
用这个递推式可以O(nk)求出斯特林数。
恒等式5
{nk}=j=0∑n−1(n−1j)⋅{n−j−1k−1}
把n个元素分成k组,考虑最后一个元素和哪些元素在同一个组。假如同组的还有j个其它元素,那么这j个元素的选择就是组合数。剩下的元素分k−1组。
恒等式6
P(n,k)=P(n−1,k−1)+P(n−k,k)
把n拆成k个元素的和,考虑拆出来的数字里有没有1。如果有1,那么剩下的n−1拆成k−1个数字;如果没有1,说明拆除来的每个数都大于1,那么可以给每个数都削掉一个1,变成n−k拆成k个数字,之后可以随便拆分。
用这个递推式可以O(nk)求出划分数。
恒等式7
P(n,k)=j=0∑kP(n−k,j)
把n拆成k个元素的和,考虑拆出来的数字里有多少个1。如果有k−j个1,那么剩下的j个数都大于1。除去所有的1,后面总共有n−k+j个数,全都削掉1,转化成n−k拆成j个数。
恒等式8
j=0∑n(−1)j(jn)(n2n+k−2j)=2n
从(0,0)出发,每次只能向右或向上走,先走到(n,n),再一路往右走到(n+k,n)。在从(0,0)走到(n,n)的过程中,总共走2n步。规定∀i∈[n],第2i−1步和第2i步不能都向右走。
两步为一组看这个问题,每组只有右上和上右两种情况,最后的k步一定全部向右,因此总的方案数就是2n。
用容斥原理来计算(见下一篇文章)。假设对于i∈[n],如果第2i−1步和第2i步都向右走了,就称这次走路在坏集合Ai内。设J={Ai1,⋯,Ait},那么N≥(J)应当这样计算,总共走2n+k步,现在已经确定了有2t步,剩下的2n+k−2t步里必须有n步是向上走的,因此N≥(J)=(n2n+k−2t)。根据容斥,总方案数应当是N=(∅)=j=0∑n(−1)jJ∈(jA)∑N≥(J)=j=0∑n(−1)j(jn)(n2n+k−2j)。
参考资料
[1] Chihao Zhang, Combinatorics in Computer Science (Spring 2023)