【HDU 2013 猴子吃桃子】 尾递归与迭代
大一时的一道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 猴子吃桃子】 尾递归与迭代的更多相关文章
- HDU 5297 Y sequence 容斥 迭代
Y sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5297 Description Yellowstar likes integer ...
- HDU 4089 Activation:概率dp + 迭代【手动消元】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4089 题意: 有n个人在排队激活游戏,Tomato排在第m个. 每次队列中的第一个人去激活游戏,有可能 ...
- HDU 2013 (水)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2013 题目大意:已知最后一天桃子只有一个,告诉你猴崽子第一天吃掉总桃子数的一半多一个,第二天吃掉剩下总 ...
- HDU 2013 蟠桃记
蟠桃记 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- HDU 2013(递归)
Problem Description 喜欢西游记的同学肯定都知道悟空偷吃蟠桃的故事,你们一定都觉得这猴子太闹腾了,其实你们是有所不知:悟空是在研究一个数学问题!什么问题?他研究的问题是蟠桃一共有多少 ...
- HDU - 5297:Y sequence (迭代&容斥)
Yellowstar likes integers so much that he listed all positive integers in ascending order,but he hat ...
- 【视频+图文】Java经典基础练习题(六):猴子吃桃子问题
目录 一.具体题目 二.视频讲解 三.思路分析(逆向思维) 四.代码+结果 代码: 结果: 五.彩蛋 一.具体题目 猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个 第二天 早上又将剩下 ...
- hdu 2013
水题 AC代码: #include <iostream> using namespace std; int main() { int i,m,n; while(cin>>n) ...
- hdu 4709 Herding hdu 2013 热身赛
题意:给出笛卡尔坐标系上 n 个点,n不大于100,求出这些点中能围出的最小面积. 可以肯定的是三个点围成的面积是最小的,然后就暴力枚举,计算任意三点围成的面积.刚开始是求出三边的长,然后求面积,运算 ...
随机推荐
- 2013Q1全球网速排名 韩国第1美国第9 中国呐?(图)
德国著名统计公司Statista,最近公布了2013 Q1季度全球互联网网速排名数据.其中,韩国以平均14.2Mbps的网速继续排名世界第一. 此外,第二至第十名的国家和地区分别为:日本(11.7 M ...
- java设计模式--创建模式--原型模式
原型模式: 原型模式 概述 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 适用性 .当一个系统应该独立于它的产品创建.构成和表示时. .当要实例化的类是在运行时刻指定时,例如,通过 ...
- ##解决 ViewPager 调用 notifyDataSetChanged()无刷新:原理、解决办法##
一.原理 转自:http://www.cnblogs.com/maoyu417/p/3740209.html 转载 http://www.67tgb.com/?p=624 最近项目结束,搞了一次代码分 ...
- mongoDb c driver
1,yum dependencies Centos,RHEL Fedora: $ sudo yum install git gcc automake autoconf libtool Debian: ...
- PCRE-正则库及用法
摘自http://blog.chinaunix.net/uid-26575352-id-3517146.html 在C语言中利用PCRE实现正则表达式 http://www.pcre.org/ ...
- PHP MySQL Update 之 Update
更新数据库中的数据 UPDATE 语句用于在数据库表中修改数据. 语法 UPDATE table_name SET column_name = new_value WHERE column_name ...
- Unity屏幕射线碰撞
Layers层: 从Layers设置看来,最多支持32层. 图层的值开始依次 0^2,1^2, 2^2, 3^3 依次增加. 当摄像机Culling Mask属性 Nothing= –1 Eveni ...
- mysql的wait_timeout配置
mysql数据库有一个wait_timeout的配置,默认值为28800(即8小时). 在默认配置不改变的情况下,如果连续8小时内都没有访问数据库的操作,再次访问mysql数据库的时候,mysql数据 ...
- Hibernate中save、saveorupdate、persist方法的区别
在Hibernate中,save().saveOrUpdate()和persist()都是用于将对象保存到数据库中的方法,但其中有些细微的差别.例如,save()只能INSERT记录,但是saveOr ...
- jquery第一期:运行第一个jquery
首先下载js文件,网址jquery.com去下载,可以下载1.10版的 首先打开editplus进行编辑,添加js文件: 编写代码: <!DOCTYPE html PUBLIC "-/ ...