组合数学中正整数的分拆个数
分拆:将自然数
n
n
n 写成递降正整数和的表示
将
n
n
n 分成恰有
k
k
k 个部分的分拆,称为
k
k
k部分拆数,记作
p
(
n
,
k
)
p(n,k)
p(n,k)
直接上代码:
第一个递推方法在原理2中有
我直接抄过来(CV助手):
#include <stdio.h>
#include <string.h>
int p[10005][1005]; /*将自然数n分拆为k个部分的方法数*/
int main() {
int n, k;
while (~scanf("%d%d", &n, &k)) {
memset(p, 0, sizeof(p));
p[0][0] = 1;
int i;
for (i = 1; i <= n; ++i) {
int j;
for (j = 1; j <= k; ++j) {
if (i - j >= 0) /*p[i-j][j]所有部分大于1*/
{
p[i][j] = (p[i - j][j] + p[i - 1][j - 1]) %
1000007; /*p[i-1][j-1]至少有一个部分为1。*/
}
}
}
printf("%d\n", p[n][k]);
}
}
第二个递推方法(我自己写的)
#include <iostream>
using namespace std;
int numSplit(int n, int k) // 分拆数的计算函数
{
int sum = 0;
if (k == 1 || n == k) // B(n,1) = B(n,n) = 1
sum += 1;
else if (k == 2) // B(n,2) = n/2(向下取整)
sum += n / 2;
else if (n > k) // B(n,k) = B(n-k,k) + B(n-k,k-1) + ... + B(n-k,1)
{
for (int i = 1; i <= k; i++)
{
sum += numSplit(n - k, i);
}
}
return sum;
}
int main()
{
cout << "B(9,6) = " << numSplit(9, 6) << endl;
cout << "B(10,6) = " << numSplit(10, 6) << endl;
return 0;
}
输出:
B(9,6) = 3
B(10,6) = 5