递归算法--写实例----阶乘问题---整数划分问题
一个自己或间接调用自身的算法叫递归算法。
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); }