大一时的一道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,可直接写出如下递归函数:

 int sum(int x){
if(x==n) return ;
return *sum(x+) + ;
}

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

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

 ans=;
int i=;
while(i++ < n){
ans = *ans + ;
}

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

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

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

 int fib(int n){
if(n==) return ;
if(n==) return ;
return fib(n-)+fib(n-);
}

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

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

 int fibI(int n){
int f=, g=; // fib(0), fib(1)
int i=;
while(i++ < n){
g = g + f; // fib(n) = fib(n-1) + fib(n-2)
f = g - f; // fib(n-1) = fib(n) - fib(n-2)
}
return g; // fib(n)
}

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

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

【HDU 2013 猴子吃桃子】 尾递归与迭代的更多相关文章

  1. HDU 5297 Y sequence 容斥 迭代

    Y sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5297 Description Yellowstar likes integer ...

  2. HDU 4089 Activation:概率dp + 迭代【手动消元】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4089 题意: 有n个人在排队激活游戏,Tomato排在第m个. 每次队列中的第一个人去激活游戏,有可能 ...

  3. HDU 2013 (水)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2013 题目大意:已知最后一天桃子只有一个,告诉你猴崽子第一天吃掉总桃子数的一半多一个,第二天吃掉剩下总 ...

  4. HDU 2013 蟠桃记

    蟠桃记 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  5. HDU 2013(递归)

    Problem Description 喜欢西游记的同学肯定都知道悟空偷吃蟠桃的故事,你们一定都觉得这猴子太闹腾了,其实你们是有所不知:悟空是在研究一个数学问题!什么问题?他研究的问题是蟠桃一共有多少 ...

  6. HDU - 5297:Y sequence (迭代&容斥)

    Yellowstar likes integers so much that he listed all positive integers in ascending order,but he hat ...

  7. 【视频+图文】Java经典基础练习题(六):猴子吃桃子问题

    目录 一.具体题目 二.视频讲解 三.思路分析(逆向思维) 四.代码+结果 代码: 结果: 五.彩蛋 一.具体题目 猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个  第二天 早上又将剩下 ...

  8. hdu 2013

    水题 AC代码: #include <iostream> using namespace std; int main() { int i,m,n; while(cin>>n) ...

  9. hdu 4709 Herding hdu 2013 热身赛

    题意:给出笛卡尔坐标系上 n 个点,n不大于100,求出这些点中能围出的最小面积. 可以肯定的是三个点围成的面积是最小的,然后就暴力枚举,计算任意三点围成的面积.刚开始是求出三边的长,然后求面积,运算 ...

随机推荐

  1. dp 46(再做一遍)

    Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955 背包;第一次做的时候把概率当做背包(放大100000倍化为整数):在此范围内最多能抢多 ...

  2. 求解答,Android源码编译时怎样添加第三方jar包

    各位大神好,遇到的问题如标题. 我用Eclipse写了一个android工程,但是这个工程需要到SDK的隐藏类,所有想在源码下编译,但是每次mm之后,都会出现错误,提示是找不到对应的类. 我需要加入的 ...

  3. Kyoya and Colored Balls(组合数)

    Kyoya and Colored Balls time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  4. Riak VClock

    Riak VClock 关于向量时钟的概念.在这里就多讲了,大家能够參照一下Dynamo的论文了解一下,向量时钟在分布式主要用于解决一致性性问题.能够和CRDTs一起看. 以下的源码是參照riak中的 ...

  5. SPOJ GCDEX (数论)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:求sigma (gcd (i , j))  ...

  6. Java并发编程学习笔记 深入理解volatile关键字的作用

    引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深入研究一下java并发方面的知识.网上关于volatile的 ...

  7. java中List的用法

    list的添加删除等操作 import java.util.*; class TestList { public static void main(String[] args) { List<S ...

  8. ArcGIS添加鹰眼

    axMapControl1是主地图 axMapControl2是鹰眼地图 private void axMapControl1_OnExtentUpdated(object sender, IMapC ...

  9. 【初级坑跳跳跳】第一个应用布局学习的代码运行时出错(manifest里未将activity先注册,控件错误)

    首先,根据书中想要实现的结果,看了下书中代码,大致知道布局是怎么样的,然后根据图片自己写xml, 1.运行时第一个坑是 忘记在AndroidManifest.xml里先注册activity,导致运行时 ...

  10. Hibernate 关联关系映射实例

    双向多对一/一对多(many-to-one/one-to-many) 例子,多个学生对应一个班级,一个班级对应多个学生: 班级类,Grade.java: public class Grade { pr ...