递归算法--写实例----阶乘问题---整数划分问题

一个自己或间接调用自身的算法叫递归算法。

 

1、求阶乘n!

   第一步:递推表达式  f(n) = {1,n*f(n-1)}  前者:当 n=0(递归终止条件)   后者:n>0

   第二步:清楚返回值是什么

              调用f(0)   返回值为 1

              调用f(1)   返回值为 1*f(0)

              调用f(2)   返回值为 1*f(1)

              调用f(3)   返回值为 1*f(2)

              依次类推

              调用f(n)   返回值为 n*f(n-1)

                                                      所以,f(0)返回值是1   其他的返回值是 n*f(n-1)

 

int f(int n)
{
    if(n==0)
    {
        return 1;
    }
    else
    {
        return  n*f(n-1);
    }
}

 

2、Fibonacci数列递归算法

第一步:递推表达式 f(n)={0,1,f(n-1)+f(n-2)}

 

3、整数划分问题

问题描述:将整数n表示为正整数之和,问n有几种表示方法.

问题分析: n=m1+m2+...+mi; (其中mi为正整数,并且1 <= mi <= n),则{m1,m2,...,mi}为n的一个划分。
               如果{m1,m2,...,mi}中的最大值不超过m,即max(m1,m2,...,mi)<=m,则称它属于n的一个m划分。这里我们记n的m划分的个数为f(n,m);

 

分类讨论

 

最重要的讨论m<n

 (5) n>m时,根据划分中是否包含最大值m,可以分为两种情况:
               (a). 划分中包含m的情况,即{m, {x1,x2,...xi}}, 其中{x1,x2,... xi} 的和为n-m,因此这种情况下 m可以忽略不计 
                     f(n,m)等同于f(n-m,m)   表示正整数n-m,最大值为m的划分数


               (b). 划分中不包含m的情况,则划分中所有值都比m小,即n的(m-1)划分,个数为f(n,m-1);
              因此 f(n, m) = f(n-m, m)+f(n,m-1);

 

实际上:是将数 逐渐 拆为1的过程,通过一些分类讨论,将大数拆为最基本的1+1+1.....+1

     

# include<iostream>
using namespace std;
int PartitionHelp(int n,int m)
{
    if(n<1 || m<1)
    {
        return 0;
    }
    
    else if(n==1 || m==1)   //n为1时,已经是最小的正整数,故只有一种分法   m为1时即可划分的最大值不超过1,也只有1种分法即 n=1+1+....+1 
    {
        return 1;
    }
    
    else if(n<m)            //当m>n时 因为最大值 m 最大不超过n  所以将m替换成n
    { 
        return PartitionHelp(n,n);
    }
    
    
    else if(n==m)           //当m==n时 ,最大值为m的只有一种,剩下的由 最大值m<=n-1 组成
    {
        return PartitionHelp(n,n-1)+1;
    }
    
    
    else   //最核心的步骤:当1<m<n时
    {
        return PartitionHelp(n,m-1) + PartitionHelp(n-m,m);
    }
    
}

int Partition(int n)
{
    return PartitionHelp(n,n);
}

 

posted on 2017-01-21 20:06  qq77530202  阅读(483)  评论(0编辑  收藏  举报