整数划分问题

整数划分问题:

将一个正整数n表示成一系列正整数之和,n=n[1]+n[2]+...+n[k],其中n[1]>=n[2]>=...>=n[k]>=1,k>=1。正整数n的一个这种表示称为n的一个划分。求n的不同划分个数。  

 

 

用递归算法求解:

(1)递归子结构性质:

显然n的一个划分中包含了某个子问题t(<n)的一个划分。这里问题的解是划分数,关键是要研究用子问题的划分数来定义原问题的划分数。在n的所有不同划分中,将其中最大加数n[1]不大于m的划分数个记作q(n,m),则q(n,n)为原问题的解。递归定义如下:  

1)当n<1或m<1时,显然q(n,m)=0;  

2)当m=1时,n只有一种划分形式,n=1+1+...+1,共n个1相加。q(n,1)=1;  

3)当n=1时,显然也只有一种划分形式,q(1,m)=1;  

4)当n<m时,因为n[1]不能大于n,故q(n,m)=q(n,n);  

5)当n=m时,q(n,n)为n的所有划分个数,它由n[1]<=n-1的划分和n[1]=n的划分(只有一个)组成,q(n,n)=q(n,n-1)+1;  

6)当n>m>1时,n[1]不大于m的划分,由n[1]<=m-1的划分和n[1]=m的划分(相当于将剩下的n-m划分成不大于m的划分)组成,q(n,m)=q(n,m-1)+q(n-m,m)。  

(2)递归终止条件:

上述1),2),3)即为递归的终止条件。

在分析递归终止条件时特别注意要使所有的子问题都能递归终止,否则如果某个子问题不能递归终止,会导致无穷的递归调用。

int q(int n,int m){
    if((n<1) || (m<1))  return 0;
    if((n==1) || (m==1))  return 1;
    if(n<m)  return q(n,n);
    if(n==m)   return q(n,m-1)+1;
    return q(n,m-1)+q(n-m,m);    
}

递归算法结构简洁清晰,可读性强,但运行时间和占用的存储空间一般都比非递归算法要多。系统是通过栈结构来完成递归的展开,因此若要把递归算法转化为非递归算法,通常是采用一个用户定义的栈来模拟系统的调用工作栈,以达到消除递归的目的。

posted @ 2014-08-29 23:02  mmcmmc  阅读(199)  评论(0编辑  收藏  举报