算法之递归算法(三)

本文探讨了如何使用递归方法解决涉及两个参数的问题,如计算最大公约数。通过实例和公式f(a,b)=f(b%a,a),理解了如何通过减小参数规模到达临界条件。后续还介绍了用递归解决苹果分配问题的思路,展示了多参数递归的实践应用。
摘要由CSDN通过智能技术生成

前一篇我们使用小明跳楼梯的例子说明了递归函数求解的方法:递归函数求解的方法
这一篇我们继续了解递归算法的内容。对于一个参数的递归函数,我们找到了一种通用的方法,那就是直接寻找f(n)f(n-1)之间的关系即可。但对于有些问题,一个参数是不够的。这一篇,我们将查看一个使用两个参数的递归算法练习题来讲解相关内容。

给定两个整数,计算其最大公约数和最小公倍数。

这个题干很简单,就是求最大公约数。如果你的第一反应是从大到小进行循环,如果某一个数刚好能够被这两个数整除,这个数字就是最大公倍数的话,这一篇可能是比较适合你的。
首先,我还是希望简单聊一下什么叫最大公约数。比如说,12的因数有1,2,3,4,6,12,而18的因数有1,2,3,4,6,9,18,这两个数字公共的因数有1,2,3,4,6,而6是其中最大的一个。因此,1218的最大公约数为6。在这个推理中,我们发现6正好是1218的差。那么最大公约数等于两个数之差吗?显然这个结论是错误的。当我们举例1030时,结果最大公约数是10并不是相差的20,但我们发现,2010的差是10。难道说这个差是减多次?我们可以使用求余运算表示减多次,求余运算的减多次指的是一直减,直到不能减为止。也就是余数必须小于除数。当我们把求余运算放在1030之间,得到的结果是0。而1218之间使用求余运算得到结果为6。这之间似乎没有任何规律。但我们都注意到,在求余运算中,都出现了我们想要的数字106
其实,如果我们稍作注意,也会发现一些规律,比如说,1218的差与12的最大公约数是相同的,都是61218进行求余运算的结果612的最大公约数相同。放在1030之间也是一样的。那么我们推断,ab的最大公约数与a%bb的最大公约数相同
这个结论是否正确呢?我们在举一些实例来证明,3648的最大公约数等于48%3636的最大公约数吗?答案是肯定的。那么按照这个道理,我们就可以得到这样的一个公式:f(a,b) = f(b%a, a)。那么临界条件呢?当a==0时,不能在进行求余运算了,也就是结束的时候了。

int f(int a, int b)
{
	if(a == 0)
		return b;	//此时b为最大公约数
	return f(b%a, a);
}

这是包含两个参数的递归函数,在这个函数中,并不想上一篇一样,直接寻找f(n-1)f(n)之间的关系,而是减少参数的规模。参数不断减少,不断接近临界值,最终通过临界值得到结果。这是递归算法的真谛。下面这个例子能很好的说明。

将m个相同的苹果,放在k个相同的盘子里,问一共有多少种方法?

在这个问题中,我们想到的是能否定义一个f(m,k的递归函数来求解呢?如果可以,我们就需要找到临界值与减少参数规模的规律。我们可以先找临界值,这个通常会简单一些,当只有一个苹果的时候,只有一种方法。不仅如此,当只有一个盘子的时候,也只有一种方法。还有其他情况吗?当然,如果有10个盘子,只有3个苹果,不论怎么放,一定至少会有7个盘子是空的,因此,这种情况可以看做3个苹果放在3个盘子里即可。
排除掉这些临界状态,其他的如何考虑呢?第一种,有空盘子。如果有空盘子的话,我们可以考虑空一个盘子的情况,毕竟如果空两个盘子的话,也可以通过空一个盘子推导出来。那么,空一个盘子该如何处理呢?如果空一个盘子的话,我们就需要把m个苹果放在k-1个盘子里。第二种,没有空盘子。为了保证没有空盘子,我们可以先将每一个盘子里放一个苹果,那么还剩下m-k个苹果。这m-k个苹果可以放在k个盘子中。这样的话,对于f(m,k)我们拆解成两个方案的总和,也就是f(m,k)=f(m-k,k) + f(m,k-1).这样减少了参数规模,使得递归函数可以正常进行下去。我们尝试使用代码描述具体的方案吧。

int f(int m, int k)
{
	if(k <= 1 || m <= 1)
		return 1;
	if(m < k)	//苹果没有盘子多
		return f(m, m);
	return f(m-k, k) + f(m, k-1);
}

这样的话,关于递归算法对于多个参数的求解方法也已经描述清晰了。希望能给你一些启示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值