开发者社区> helena_wang> 正文

【HDU 2013 猴子吃桃子】 尾递归与迭代

简介: 大一时的一道C语言练习题,可作为递归和尾递归转迭代的范例。HDU 2013 http://acm.hdu.edu.cn/showproblem.php?pid=2013 题意:猴子摘了sum个桃子,从第1天开始,每天吃掉剩余桃子的一半多一个,第n天时只剩1个桃子,求sum值。
+关注继续查看

大一时的一道C语言练习题,可作为递归和尾递归转迭代的范例。HDU 2013 http://acm.hdu.edu.cn/showproblem.php?pid=2013

题意:猴子摘了sum个桃子,从第1天开始,每天吃掉剩余桃子的一半多一个,第n天时只剩1个桃子,求sum值。

分析:设第 i 天在开吃之前所剩的桃子数为sum(i),第 i 天要吃掉的桃子数为f(i),

则问题可表示为:已知sum(n)=1 和如下两个关系式:

  f(i) = sum(i)/2 + 1      (1)

  sum(i+1) = sum(i) - f(i)    (2)

  求sum(1)。

求解:(1)(2)式联立,可得递推式sum(i+1) = 2*sum(i) + 2。加上递归基sum(n)=1,可直接写出如下递归函数:

1 int sum(int x){
2     if(x==n) return 1;
3     return 2*sum(x+1) + 2;
4 }

在主函数中调用sum(1)即可得答案。

上面的递归函数属于尾递归(递归调用在最后一步),可以比较直观地转成迭代形式。只需从递归基出发进行n-1次迭代,即可得到同样的结果。代码如下:

1 ans=1;
2 int i=1;
3 while(i++ < n){
4     ans = 2*ans + 2;
5 }

这道题的迭代相比递归,省去了n-1层调用栈,空间复杂度从O(n)降到O(1),时间复杂度仍为线性的O(n)。

 

下面再来看一道尾递归转迭代的问题:Fibonacci数。

递推式 fib(n) = fib(n-1) + fib(n-2),递归基fib(0)=0, fib(1)=1。可写出如下递归函数:

1 int fib(int n){
2     if(n==0) return 0;
3     if(n==1) return 1;
4     return fib(n-1)+fib(n-2);
5 }

通过递归树分析,这一递归版包含了很多的重叠子问题,时间复杂度为O(2n),空间复杂度O(n)。

不过它同样属于尾递归,因而可以较方便地转为迭代版:

1 int fibI(int n){
2     int f=0, g=1;     // fib(0), fib(1)
3     int i=1;
4     while(i++ < n){
5         g = g + f;     // fib(n) = fib(n-1) + fib(n-2)
6         f = g - f;     // fib(n-1) = fib(n) - fib(n-2)
7     }
8     return g; // fib(n)
9 }

这里的两个变量f, g在每次迭代后都保存相邻两项fibonacci数,二者滚动向前(图片来自MOOC: TsinghuaX: 30240184X 数据结构(2015秋)),直至抵达最终的fib(n)。

此迭代版本只包含一个线性的while循环,因此时间复杂度为O(n),仅用两个变量暂存,故空间复杂度为O(1)。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阶乘约数+猴子分香蕉(蓝桥杯JAVA解法)
阶乘约数+猴子分香蕉(蓝桥杯JAVA解法)
47 0
【兔年之兔子走迷宫】 用一个小游戏对回溯法进行实现 | C++
简单的来说,算法就是用计算机程序代码来实现数学思想的一种方法。学习算法就是为了了解它们在计算机中如何演算,以及在当今的信息时代,它们是如何在各个层面上影响我们的日常生活的,从而提高我们的逻辑思维能力和处理实际问题的能力。善用算法、巧用算法,是培养程序设计逻辑的重中之重,许多实际的问题都可用多个可行的算法来解决, 但是要从中找出最优的解决算法却是一项挑战。
381 0
猴子吃桃子问题(循环、递归)
猴子吃桃子问题(循环、递归)
48 0
蓝桥杯 算法 猴子吃包子、 查找整数
蓝桥杯 算法 猴子吃包子、 查找整数
43 0
7-5 猴子吃桃问题
7-5 猴子吃桃问题 (20分) >一只猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个;第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半加一个。
93 0
【刷穿 LeetCode】第 N 个泰波那契数 :「迭代」&「递归」&「矩阵快速幂」&「打表」
【刷穿 LeetCode】第 N 个泰波那契数 :「迭代」&「递归」&「矩阵快速幂」&「打表」
64 0
不管是青蛙跳台阶还是who爬楼梯,能上去就行
爬楼梯这个问题也是一个很经典的面试题,可以换各种人物动物,比如青蛙、小兔子跳台阶,张三李四爬楼梯等等。
85 0
漫画:动态规划解决扔鸡蛋问题
在上一篇漫画中,小灰介绍了一道有趣的智力题:漫画:有趣的扔鸡蛋问题那么,如何利用动态规划来求出扔鸡蛋问题的通解? 换句话说,有M层楼 / N个鸡蛋,要找到鸡蛋摔不碎的临界点,需要尝试几次?
160 0
+关注
helena_wang
&quot;The master has failed more times than the beginner has even tried.&quot;
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载