【2-5】整数划分问题
20200923
参考链接:https://blog.csdn.net/weixin_35909255/article/details/54896972
1.问题描述
将正整数n表示成一系列正整数之和,
正整数n的这种表示称为正整数n的划分。正整数n的不同的划分个数称为正整数n的划分数,记作。
2.问题分析
我们将最大加数不大于m的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系:
(1)q(n,1)=1,n>=1
当最大加数a不大于1时,任何正整数n只有一种划分形式,即1+1+1+……+1
(2)q(n,m)=q(n,n),
最大加数a实际上不能大于n,因此q(1,m)=1
(3)q(n,n)=1+q(n,n-1)
正整数n的划分有最大加数a=n的划分和最大加数a<=n-1的划分组成
(4)q(n,m)=q(n,m-1)+q(n-m,m), n>m>1
正整数n的最大加数a不大于m的划分由最大加数a=m的划分和划分和最大加数a<=m-1的划分组成
最后一个可能不是很理解,原作者的解释如下:
- (a). 划分中包含 m 的情况,即 { m, { x1, x2, ..., xi } }, 其中 { x1, x2, ..., xi } 的和为 n - m,可能再次出现 m,因此是(n - m)的 m 划分,因此这种划分个数为 q(n-m, m);
- (b). 划分中不包含 m 的情况,则划分中所有值都比 m 小,即 n 的 ( m - 1 ) 划分,个数为 q(n, m - 1);
由于不是很理解,所以根据上面的内容,我写了一个自己的相关理解。
根据上面的解释,我们可以给出计算q(n,m)的递归式如下:
3.代码实现
#include <cstdio>
int n,ans;
int fix(int pn,int pm);
int main(int argc, char* argv[])
{
while(~scanf("%d",&n))
{
ans=0;
ans=fix(n,n);
printf("%d\n",ans);
}
return 0;
}
int fix(int pn,int pm)
{
if(pn==1 || pm==1) return 1;
if(pn<pm)return fix(pn,pn);
if(pn==pm)return 1+fix(pn,pm-1);
return fix(pn,pm-1)+fix(pn-pm,pm);
}