【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)。

目录
相关文章
|
8月前
|
存储 安全 区块链
去中心化存储:数据存储的新范式
去中心化存储:数据存储的新范式
391 91
|
7月前
|
机器学习/深度学习 人工智能 前端开发
魔搭社区模型速递(3.23-3.29)
🙋魔搭ModelScope本期社区进展:619个模型,93个数据集,151个创新应用,7篇内容。
275 4
魔搭社区模型速递(3.23-3.29)
|
9月前
|
存储 人工智能 Cloud Native
NAS深度解析:面向云原生应用的文件存储
本文深入解析了面向云原生应用的文件存储NAS,由阿里云专家分享。内容涵盖Cloud Native与AI浪潮下的技术创新,包括高性能、弹性伸缩、成本优化及数据安全等方面。针对云原生应用的特点,NAS在Serverless生态中不断演进,提供多种产品规格以满足不同需求,如极速型NAS、归档存储等,确保用户在高并发场景下获得稳定低延时的存储体验。同时,通过优化挂载参数和容器访问策略,提升整体性能与可用性。
362 11
|
10月前
|
存储 测试技术 项目管理
【北京大学 软件工程】三、软件需求
本文介绍了软件需求工程的基础概念和流程。首先定义了需求及其获取,强调需求是描述系统功能、性能等方面的要求,并需具备必要性、无歧义性、可测性、可跟踪性和可测量性五大基本性质。接着阐述了需求的分类,包括功能、性能、外部接口、设计约束和质量属性五类,并详细说明了各类需求的具体内容及示例。此外,还探讨了需求发现的技术,并分析了每种技术的应用场景与优缺点。最后,文章解释了需求规约(SRS)的概念、格式和作用,指出它是软件开发组织与用户之间的技术合同,用于指导项目管理、产品设计、测试计划和用户手册的编写。需求规约不应包含设计细节或项目规划信息,而是专注于明确系统的功能性与非功能性要求。
【北京大学 软件工程】三、软件需求
|
8月前
|
存储 程序员 C语言
【C++篇】深度解析类与对象(上)
在C++中,类和对象是面向对象编程的基础组成部分。通过类,程序员可以对现实世界的实体进行模拟和抽象。类的基本概念包括成员变量、成员函数、访问控制等。本篇博客将介绍C++类与对象的基础知识,为后续学习打下良好的基础。
|
12月前
|
存储 监控 安全
|
12月前
|
数据挖掘 API 数据安全/隐私保护
淘宝商品 API 接口怎样去使用?
淘宝商品API接口为开发者和企业提供了一种强大的工具,用于高效获取和利用淘宝平台上的商品数据。本文详细介绍了从注册成为淘宝开发者、申请API权限、获取API密钥,到阅读API文档、搭建开发环境、调用API接口、处理响应结果及数据应用的全过程。通过实际案例展示了如何利用淘宝商品API接口提升电商平台和价格比较网站的竞争力,并强调了使用过程中的注意事项,如遵守API使用规范、数据安全与隐私保护等。
1854 0
|
机器学习/深度学习 Ubuntu 决策智能
ubuntu16.04中将自己的ubuntu做成镜像
ubuntu16.04中将自己的ubuntu做成镜像
716 0