整数拆分(递归算法)

所谓整数划分,是指把一个正整数n写成如下形式:

n=m1+m2+m3+…+mi;(其中mi为正整数,并且1<=mi<=n),则{m1,m2,m3,…,mi}为n的一个划分。

如果{m1,m2,m3,…,mi}中的最大值不超过m,即max{m1,m2,m3,…,mi} <= m,则称它属于n的一个m划分。

例如:当n=4时,它有5个划分:{4}、{3,1}、{2,2}、{2,1,1}、{1,1,1,1};4=1+3和4=3+1被认为是同一个划分。

我说的这个问题是输入一个整数,输出其划分数

在代码中,q(m,n)表示m是由若干个不大于n的数相加得到的。

根据n和m的关系,考虑下面几种情况:

第一种情况
m<=0并且n<=0时,肯定返回值是0;

第二种情况
m=1时,无论n等于多少,肯定只有一个划分就是{1};
n=1时,无论m等于多少,也只有一个划分就是{1,1,1,1,…,1};

第三种情况
m时,因为划分中没有负数,所以q(m,n)=q(m,m);

第四种情况
m>=n时,最普遍的情况,根据划分中是否包含n,可以分为两种情况:
(1) 包含n,即划分为{n,{x1,x2,x3,…,xi}},其中{x1,x2,x3,…,xi}的和为m-n,其中在后来的划分中还有可能包含n,所以q(m,n)=q(m-n,n)
(2) 不包含n,则这些划分的整数中所有数都比n小,即不大于n-1,即m是由若干个不大于n-1的数相加得到的,所以q(m,n)=q(m,n-1)
所以第四种情况递归式为q(m,n)=q(m,n-1)+q(m-n,n)

其实第四种情况还细分可以分为m>n与m=n;
m=n也可以分两种情况
(1)划分中包含m的情况,只有一个,即{m};
(2)划分中不包含m的情况,这时划分中最大的数字也一定比m小,即m的所有(m-1)划分,即m是由若干个不大于(m-1)的数相加得到;
因此,q(m,m) = 1 +q(m,m-1)
此处可以详细的分一下,其实也无所谓,因为你代入公式q(m,n)=q(m,n-1)+q(m-n,n)
后者q(m-m,m)再多递归一下就return 0了;
但是我的代码中没有分。

#include	
int q(int m,int n){			//m是由若干个不大于n的数相加 
	if(m<=0||n<=0) return 0;
	if(m==1||n==1) return 1;
	if(m==n) return (1+q(m,n-1));
	if(mn) return (q(m,n-1)+q(m-n,n)); 
} 
int main(){
	int t;
	scanf("%d",&t);
	int x=q(t,t);
	printf("%d\n",x);	
	return 0;
}

你可能感兴趣的:(算法)