所谓整数划分,是指把一个正整数n写成为
其中,
为正整数,并且
;
为n的一个划分。
如果
中的最大值不超过m,即
,则称它属于n的一个m划分。
这里我们记n的m划分的个数为
。
例如,当n=4时,有5个划分,即
,
,
,
,
。
注意:
和
被认为是同一个划分。
根据n和m的关系,考虑一下几种情况:
(一)当
时,无论m的值为多少
,只有一种划分,即
。
(二)当
时,无论n的值为多少,只有一种划分,即n个1,
。
(三)当
时,根据划分中是否包含n,可以分为以下两种情况:
(1)划分中包含n的情况,只有一个,即
。
(2)划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有
划分。
因此
。
(四)当
时,由于划分中不可能出现负数,因此就相当于
。
(五)当
时,根据划分中是否包含最大值m,可以分为以下两种情况:
(1)划分中包含m的情况,即
,其中
的和为n-m,因此这种情况下为
。
(2)划分中不包含m的情况,则划分中所有值都比m小,即n的
划分,个数为
。
因此
。
综上所诉:
20 以内的一个数:
#include <stdio.h>
int main()
{
int s, i, j, k, t, u;
int s, i, j, k, t, u;
static int a[21][800][21];
printf("input s(s<=20):"); scanf_s("%d", &s);
a[2][1][1] = 1; a[2][1][2] = 1; a[2][2][1] = 2;
u = 2;
for (k = 3; k <= s; k++)
{
for (j = 1; j <= u; j++)
for (j = 1; j <= u; j++)
{
a[k][j][1] = 1;
a[k][j][1] = 1;
for (t = 2; t <= k; t++) // 实施在k−1所有划分式前加1操作
a[k][j][t] = a[k-1][j][t-1];
}
for (i = u, j = 1; j <= u; j++)
if (a[k-1][j][1]<a[k-1][j][2]) // 若k−1划分式第1项小于第2项
{
i++; // 第1项加1为k的第i个划分式的第1项
i++; // 第1项加1为k的第i个划分式的第1项
a[k][i][1] = a[k-1][j][1] + 1;
for (t = 2; t <= k-1; t++)
a[k][i][t] = a[k-1][j][t];
}
i++; a[k][i][1] = k; // k的最后一个划分式为:k=k
u = i;
}
for (j = 1; j <= u; j++) // 输出s的所有划分式
{
printf("%3d: %d=%d", j, s, a[s][j][1]);
printf("%3d: %d=%d", j, s, a[s][j][1]);
i = 2;
while (a[s][j][i]>0)
{
printf("+%d", a[s][j][i]); i++;
}
printf("+%d", a[s][j][i]); i++;
}
printf("\n");
}
return 0;
}
return 0;
}