这是本文档旧的修订版!
以下内容参考自北大版《组合数学》。
分拆:将自然数n写成递降正整数和的表示。
$$n=r_1+r_2+⋯+r_k\quad r_1≥r_2≥⋯≥r_k≥1$$
和式中每个正整数称为一个部分。
分拆数:p_n。自然数n的分拆方法数。
自0开始的分拆数:
n | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |||||||||
p_n | 1 | 1 | 2 | 3 | 5 | 7 | 11 | 15 | 22 |
其中恰有k个部分的分拆,称为k部分拆数,记作p(n,k)。
本题要求计算k部分拆数p(n,k)。多组输入,其中n上界为10000,k上界为1000,对1000007取模。
显然,k部分拆数 p(n,k)同时也是下面方程的解数:
$$n-k=y_1+y_2+⋯+y_k\quad y_1≥y_2≥⋯≥y_k≥0$$
如果这个方程里面恰有j个部分非0,则恰有p(n-k,j)个解。因此有和式:
$$p(n,k)=∑_{j=1}^k p(n-k,j)$$
相邻两个和式作差,得:
$$p(n,k)=p(n-1,k-1)+p(n-k,k)$$
如果像组合数一样列出表格,每个格里的数,等于左上方的数,加上该格向上方数,所在列数个格子中的数。
下n右k | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ||||||||||
-1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||||
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||||
1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||||
2 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||||
3 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | ||||||||||
4 | 0 | 0 | 1 | 2 | 1 | 1 | 0 | 0 | 0 | 0 | ||||||||||
5 | 0 | 0 | 1 | 2 | 2 | 1 | 1 | 0 | 0 | 0 | ||||||||||
6 | 0 | 0 | 1 | 3 | 3 | 2 | 1 | 1 | 0 | 0 | ||||||||||
7 | 0 | 0 | 1 | 3 | 4 | 3 | 2 | 1 | 1 | 0 | ||||||||||
8 | 0 | 0 | 1 | 4 | 5 | 5 | 3 | 2 | 1 | 1 |
因此按列更新对于存储更有利。根据这个可以轻易地写出程序。
生成函数:一种幂级数。各项的系数为数列中的对应项。
由等比数列求和公式,有:
$$\frac{1}{1-x^k }=1+x^k+x^2k+x^3k+⋯$$
$$1+p_1 x+p_2 x^2+p_3 x^3+⋯=\frac{1}{1-x} \frac{1}{1-x^2} \frac{1}{1-x^3}…$$
对于k部分拆数,生成函数稍微复杂。具体写出如下:
$$∑_{n,k=0}^∞ {p(n,k) x^n y^k }=\frac{1}{1-xy} \frac{1}{1-x^2 y} \frac{1}{1-x^3 y}…$$
Ferrers图:将分拆的每个部分用点组成的行表示。每行点的个数为这个部分的大小。
根据分拆的定义,Ferrers图中不同的行按照递减的次序排放。最长行在最上面。
例如:分拆12=5+4+2+1的Ferrers图。
将一个Ferrers图沿着对角线翻转,得到的新Ferrers图称为原图的共轭,新分拆称为原分拆的共轭。显然,共轭是对称的关系。
例如上述分拆12=5+4+2+1的共轭是分拆12=4+3+2+2+1。
最大k分拆数:自然数n的最大部分为k的分拆个数。
根据共轭的定义,有显然结论:
最大k分拆数与k部分拆数相同,均为p(n,k)。
互异分拆数:〖pd〗_n。自然数n的各部分互不相同的分拆方法数。(Different)
n | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |||||||||
pd_n | 1 | 1 | 1 | 2 | 2 | 3 | 4 | 5 | 6 |
本题要求计算互异分拆数〖pd〗_n。多组输入,其中n上界为50000,对1000007取模。
同样地,定义互异k部分拆数pd(n,k),表示最大拆出k个部分的互异分拆,是这个方程的解数:
$$n=r_1+r_2+⋯+r_k\quad r_1>r_2>⋯>r_k≥1$$
完全同上,也是这个方程的解数:
$$n-k=y_1+y_2+⋯+y_k\quad y_1>y_2>⋯>y_k≥0$$
这里与上面不同的是,由于互异,新方程中至多只有一个部分非零。有不变的结论:恰有j个部分非0,则恰有pd(n-k,j)个解,这里j只取k或k-1。因此直接得到递推:
$$pd(n,k)=pd(n-k,k-1)+pd(n-k,k)$$
同样像组合数一样列出表格,每个格里的数,等于该格上一行左数,所在列数个格子中的数,加上该格向上方数,所在列数个格子中的数。
下n右k | -1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ||||||||||
-1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||||
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||||
1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||||
2 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | ||||||||||
3 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | ||||||||||
4 | 0 | 0 | 1 | 2 | 1 | 1 | 0 | 0 | 0 | 0 | ||||||||||
5 | 0 | 0 | 1 | 2 | 2 | 1 | 1 | 0 | 0 | 0 | ||||||||||
6 | 0 | 0 | 1 | 3 | 3 | 2 | 1 | 1 | 0 | 0 | ||||||||||
7 | 0 | 0 | 1 | 3 | 4 | 3 | 2 | 1 | 1 | 0 | ||||||||||
8 | 0 | 0 | 1 | 4 | 5 | 5 | 3 | 2 | 1 | 1 |
因此按列更新对于存储更有利。代码中将后一位缩减了空间,仅保留相邻两项。