弱菜博主竟然回来写博客了 看到了有趣的数学芝士记录一下
多重集的组合计数主要是这样一类问题:
有 n n n种不同的物品,每种物品有 a [ i ] a[i] a[i]个,从中取出 k k k个物品的方案数。
Part0:
显然有如下的dp做法:
d p [ i ] [ j ] dp[i][j] dp[i][j]表示前i种物品,取出j个物品的方案数,用前缀和优化就能做到 O ( n ∗ ∑ a [ i ] ) O(n*\sum{a[i]}) O(n∗∑a[i])的时间复杂度,较为简单,故在此略去。
Part1:
首先考虑这样的数据范围:
n < 20 , a [ i ] < = 1 e 12 , k < = 1 e 14 n<20,a[i]<=1e12,k<=1e14 n<20,a[i]<=1e12,k<=1e14
solution1:
考虑构造生成函数如下:
∏ i = 1 n ∑ j = 0 a [ i ] x j = ∏ i = 1 n ( 1 + x + x 2 + x 3 + . . . + x a [ i ] ) \displaystyle\prod_{i=1}^n\sum_{j=0}^{a[i]}x^j=\displaystyle\prod_{i=1}^n(1+x+x^2+x^3+...+x^{a[i]}) i=1∏nj=0∑a[i]xj=i=1∏n(1+x+x2+x3+...+xa[i])
n n n个多项式相乘的k次方项系数即为答案,但数据范围显然不允许我们直接这样做,于是我们推推式子如下:
( 1 + x + x 2 + x 3 + . . . + x a [ i ] ) = ( 1 − x a [ i ] + 1 ) / ( 1 − x ) (1+x+x^2+x^3+...+x^{a[i]})=(1-x^{a[i]+1})/(1-x) (1+x+x2+x3+...+xa[i])=(1−xa[i]+1)/(1−x)
∏ i = 1 n ( 1 + x + x 2 + x 3 + . . . + x a [ i ] ) = ( ∏ i = 1 n ( 1 − x a [ i ] + 1 ) ) / ( 1 − x ) n \displaystyle\prod_{i=1}^n(1+x+x^2+x^3+...+x^{a[i]})=(\displaystyle\prod_{i=1}^n(1-x^{a[i]+1}))/(1-x)^n i=1∏