递归算法题练习(数的计算、带备忘录的递归、计算函数值)

递归的介绍

概念:递归是指函数直接或间接调用自身的过程。
解释递归的两个关键要素:
基本情况(递归终止条件):递归函数中的一个条件,当满足该条件时,递归终止,避免无限递归。可以理解为直接解决极小规模问题的方法。递归表达式(递归调用):递归函数中的语句,用于解决规模更小的子问题再将子问题的答案合并成为当前问题的答案。

递归如何实现

递归函数的基本结构如下:
返回类型 函数名(参数列表){基本情况(递归终止条件)
if(满足终止条件){返回终止条件下的结果递归表达式(递归调用)
}
else if{将问题分解为规模更小的子问题使用递归调用解决子问题返回子问题的结果
}

实现过程:

  • 将大问题分解为规模更小的子问题。
  • 使用递归调用解决每个子问题。
  • 通过递归终止条件来结束递归。

设计时需注意的细节:

  1. 确保递归一定能到递归出口,避免无限递归,这可能导致TLE(超时)、MLE(超内存)、或RE(运行错误)
  2. 考虑边界条件,有时候递归出口不止一个。
  3. 避免不必要的重复计算,尽可能优化递归函数的性能(例如使用记忆化)。

递归和循环的比较

递归的特点:

  1. 直观、简洁,易于理解和实现
  2. 适用于问题的规模可以通过递归调用不断减小的情况。
  3. 可以处理复杂的数据结构和算法,如树和图的遍历。(线段树)
  4. 存在栈溢出风险(栈空间一般只有8MB,所以递归层数不宜过深一般不超过1e6层)。

循环的特点:

  • 1.直接控制流程,效率较高。(常数小)
  • 2.适用于问题的规模没有明显的缩减,或者需要特定的迭代次数。(二元组)
  • 3.适合处理大部分的动态规划问题

在部分情况下,递归和循环可以相互转化。(DFS)

例题:

(一、斐波那契数列,带备忘录的递归)

已知F(1)=F(2)= 1;n>3时F(n)=F(n-1)+F(n-2)
输入n,求F(n),n<=100000,结果对1e9+7取模

如果直接使用递归,难以算出结果,需要优化

时间复杂度为O(2^n)

#include <bits/stdc++.h>  
using namespace std;
using ll = long long; // 使用别名ll代表long long  const int N = 1e5 + 9;
const ll p = 1e9 + 7; // 定义模数p  ll fib(int n) {if (n <= 2) return 1; // 基准情况  return (fib(n - 1) + fib(n - 2)) % p; // 计算并存储结果  
}int main() {int n;cin >> n;for (int i = 1; i <= n; ++i) {cout << fib(i) << '\n'; // 输出每个i的fibonacci数并换行  }return 0;
}

 优化方法:带备忘录的递归

时间复杂度为O(n)

#include <bits/stdc++.h>  
using namespace std;
using ll = long long; // 使用别名ll代表long long  const int N = 1e5 + 9;
const ll p = 1e9 + 7; // 定义模数p  ll dp[N]; // 定义dp数组作为备忘录  // 带备忘录的递归
ll fib(int n) {if (dp[n]) return dp[n]; // 如果已经计算过,直接返回结果,不需要重复计算if (n <= 2) return 1; // 基准情况  return dp[n] = (fib(n - 1) + fib(n - 2)) % p; // 计算并存储结果  
}int main() {int n;cin >> n;for (int i = 1; i <= n; ++i) {cout << fib(i) << '\n'; // 输出每个i的fibonacci数并换行  }return 0;
}

(二、数的计算)

蓝桥 OJ 760

用户登录

题目描述
输入一个自然数 n(n < 1000),我们对此自然数按照如下方法进行处理:
1.不作任何处理;
2.在它的左边加上一个自然数,但该自然数不能超过原数的一半;

3.加上数后,继续按此规则进行处理,直到不能再加自然数为止。问总共可以产生多少个数。
输入描述
输入一个正整数 n。
输出描述
输出一个整数,表示答案。
输入输出样例

思路:

我们可以将题意转化一下,转化成在右边加上自然数,因为“在左边加上0”是没有意义的,不会改变这个数字大小,所以我们在右边也不能加上0。
用一个数组a记录下数字每一位上的数字是多少,然后枚举当前位上的数字,递归的向下去求方案数并求和即可。

#include<bits/stdc++.h>
using namespace std;const int N = 20;
int a[N];int dfs(int dep)// dep表示当前的深度
{int res = 1;// 枚举当前这层可以放下哪些数字for (int i = 1; i <= a[dep - 1] / 2; ++i){a[dep] = i;res += dfs(dep + 1);}return res;
}int main()
{int n; cin >> n;a[1] = n;cout << dfs(2) << '\n';return 0;
}

(三、计算函数值)

用户登录

问题描述:

在一个神秘的世界中,有一个传说中的神秘花园,被认为蕴藏着无限的知识。但要进入这个花园,访客必须解决一道神秘数学难题,这个难题与一个特殊的数学函数——“神秘函数”S(c)——紧密相关。

神秘函数S(c)的定义:

  • 当c为0时,S(0) = 1。
  • 当c为偶数时,S(c) = S(c/2)。
  • 当c为奇数时,S(c) = S(c-1) + 1。

任务:

编写一个程序,根据输入的正整数α,计算神秘函数S(α)的值。正确解答这道难题将获得通行证,得以进入神秘花园探索知识宝藏。

输入格式:

输入包含一个正整数α(1 ≤ α ≤ 10^6),表示要求解的神秘函数问题中的参数。

输出格式:

输出一个整数,表示神秘函数S(α)的值,即成功解决问题后得到的答案。

解题思路

这道题主要思想就是递归调用,实现了对递推方程的求解问题。

首先,我们定义一个函数,它所实现的功能是返回通过神秘函数运算得到的值。

那么,我们可以分为三个部分:

  1. 当 x=0 时,我们知道通过神秘函数运算得到的值为 1,因此直接返回 1。
  2. 当 x 为偶数时,由于 S(x)=S(x/2),故我们只需要计算 S(x/2) 的值并返回即可,这时我们再次调用我们定义的函数并以 x/2 为初始值。
  3. 当 x 为奇数时,由于 S(x)=S(x−1)+1,故我们只需要计算S(x−1) 的值并返回 S(x−1)+1 即可,这时我们再次调用我们定义的函数并以 x−1 为初始值。

经过如上过程便可以得出最终结果。

#include <bits/stdc++.h>// 奇数减一会变成偶数,偶数除以2
// 等价与我们最多使用两次代价使 x 除以 2
// 除以 2 最多 log 次
// O(log)void solve(const int &Case) { int x;std::cin >> x;std::function<int(int)> S = [&](int x) {if (x == 0)return 1;if (x % 2 == 0) {return S(x / 2);}return S(x - 1) + 1;};std::cout << S(x) << '\n';
}int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int T = 1;for (int i = 1; i <= T; i++)solve(i);return 0;
}

 今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/711256.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全攻防演练:企业蓝队建设指南

第一章 概述 背景 网络实战攻防演习是当前国家、重要机关、企业组织用来检验网络安全防御能力的重要手段之一,是对当下关键信息系统基础设施网络安全保护工作的重要组成部分。网络攻防实战演习通常是以实际运行的信息系统为攻击目标,通过在一定规则限定下的实战攻防对抗,最…

认识通讯协议——TCP/IP、UDP协议的区别,HTTP通讯协议的理解

目录 引出认识通讯协议1、TCP/IP协议&#xff0c;UDP协议的区别2、HTTP通讯协议的讲解 Redis冲冲冲——缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 认识通讯协议——TCP/IP、UDP协议的区别&#xff0c;HTTP通讯协议的理解 认识通讯协议 …

第九届数学与人工智能国际会议 (ICMAI 2024)即将召开!

2024年第九届数学与人工智能国际会议将于2024年5月10-12日在中国北京召开。本届会议由北京工业大学主办&#xff0c;旨在促进应用逻辑、算法与复杂性研究&#xff0c;使用数学的方法促进人工智能理论与应用发展&#xff0c;加深学术交流与合作。我们热忱欢迎从事相关技术研究的…

开源WIFI继电器之使用说明

1、设备说明 1.1外观 1.2供电 100~240V交流输入&#xff0c;Lin接火线&#xff0c;Nin接零线。 1.3连接负载 输出信号为继电器无源信号&#xff0c;用于信号的导通和断开控制&#xff0c;最大可通过10A负载电流&#xff0c;COM为继电器公共端&#xff0c;NO为继电器常开端&a…

蓝牙耳机推荐高性价比,五大超好用蓝牙耳机推荐,赶紧上车!

​随着技术的不断进步&#xff0c;蓝牙耳机的性能和配置也在不断提升&#xff0c;各大品牌都在推出具有各种特色的产品。其中&#xff0c;音质是很多消费者最为关注的一点。因此&#xff0c;我在这里为大家推荐几款音质表现还不错的几款蓝牙耳机&#xff0c;供大家参考。 一、挑…

Java毕业设计 基于SSM SpringBoot vue购物比价网站

Java毕业设计 基于SSM SpringBoot vue购物比价网站 SSM vue 购物比价网站 功能介绍 首页 图片轮播 商品 商品分类 商品详情 评论 收藏 商品攻略 商品信息 公告栏 在线反馈 登录 注册 个人中心 我的收藏 后台管理 登录 注册商品户 个人中心 修改密码 个人信息 商品户管理 用户…

IDC 中搭建 Serverless 应用平台:通过 ACK One 和 Knative 玩转云资源

作者&#xff1a;元毅、庄宇 如何打造云上&#xff08;公共云&#xff09;、云下&#xff08;IDC 数据中心&#xff09;统一的云原生 Serverless 应用平台&#xff0c;首先我们来看一下 ChatGPT 4 会给出什么样的答案&#xff1a; 如何打造云上、云下统一的云原生 Serverless…

【CesiumJS-3】加载倾斜模型数据(3DTilest)以及修改位置

引入倾斜模型数据 // 加载3DTiles数据let tileset;try {tileset await Cesium.Cesium3DTileset.fromUrl("/api/3DTiles/b3dm_qx/tileset.json");viewer.value.scene.primitives.add(tileset); // 倾斜模型添加到场景中viewer.value.zoomTo(tileset); // 视角定位到倾…

【音视频处理】使用ffmpeg实现多个视频合成一个视频(按宫格视图)

先上结果 环境 硬件&#xff1a;通用PC 系统&#xff1a;Windows 测试有效 软件&#xff1a;ffmpeg 解决 0、命令 ffmpeg.exe -i input1.mp4 -i input2.mp4 -i input3.mp4 -i input4.mp4 -filter_complex "[0:v]scaleiw/2:ih/2,pad2*iw:2*ih[a]; [1:v]scaleiw/2:ih/2…

BioTech - 大分子药物设计 概述

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/136302202 大分子药物设计领域主要包括3个方面&#xff0c;即大环类药物设计、蛋白质与多肽类药物设计、核酸药物设计等&#xff0c;具体如下&…

DolphinScheduler——奇富科技的调度实践

目录 一、技术架构 二、业务挑战 2.1 调度任务量大 2.2 运维复杂 2.3 SLA要求高 三、调度优化实践 3.1 重复调度 3.2 漏调度 3.3 Worker服务卡死 3.4 任务重复运行 四、服务监控 4.1 方法耗时监控 4.2 任务调度链路监控 五、用户收益 原文大佬的这篇调度系统案例…

nginx使用详解--缓存

Nginx 是一个功能强大的 Web 服务器和反向代理服务器&#xff0c;它可以用于实现静态内容的缓存&#xff0c;缓存可以分为客户端缓存和服务端缓存。 客户端缓存 客户端缓存指的是浏览器缓存, 浏览器缓存是最快的缓存, 因为它直接从本地获取(但有可能需要发送一个协商缓存的请…

【XR806开发板试用】全网首发,对接腾讯云平台的血泪史

1.前面的话 在上次连夜肝出了华为云平台的帖子:https://aijishu.com/a/1060000000287434 之后,论坛里的反响平平,好评没有,点赞更无,抱着已完成任务成功白嫖一块板子的心态,把板子收在了盒子里,第二天,助手小姐姐跟我说为何不把腾讯云的做了,对于这个要求我其实是拒绝的,但是小…

Three.js-04轨道控制器

1.导入 说明&#xff1a;相机围绕目标进行轨道运动。也就是可以通过鼠标拖拽进行移动视角。 import { OrbitControls } from three/addons/controls/OrbitControls.js; 2.使用 说明&#xff1a;构造controls对象&#xff0c;再调用update方法&#xff1b;为了使效果更为明显…

十二、Qt自定义Widget组件、静态库与动态库

一、自定义Widget组件 1、自定义Widget组件 使用步骤采用提升法&#xff08;promotion&#xff09;重新定义paintEvent事件 2、实现程序 &#xff08;1&#xff09;创建项目&#xff0c;基于QWidget &#xff08;2&#xff09;添加类&#xff0c;为Widget组件提升类 #inclu…

Vue3 在SCSS中使用v-bind

template 先创建一个通用的页面结构 <template><div class"v-bubble-bg"></div> </template>js 在JS中先对需要用的数据进行定义&#xff1a; 可以是参数&#xff0c;也可以是data <script setup>const props defineProps({bgCol…

gpt批量原创文章生成器,不限制内容的生成器

在当今的数字化时代&#xff0c;内容创作是网站持续发展的重要组成部分。然而&#xff0c;对于拥有大量内容需求的网站来说&#xff0c;手动创作文章可能会耗费大量时间和精力。为了解决这一问题&#xff0c;许多GPT&#xff08;生成式预训练模型&#xff09;文章生成软件应运而…

【重温设计模式】外观模式及其Java示例

设计模式及外观模式介绍 在编程世界中&#xff0c;设计模式就如同自然界的法则&#xff0c;是一种反复出现在各种情况下的通用解决方案。设计模式可以分为创建型、结构型和行为型三大类&#xff0c;每一类都有其独特的应用场景和解决问题的方式。今天&#xff0c;我们要重点解…

【HbuilderX】 uniapp实现 android申请权限 和 退出app返回桌面

目录 android申请权限&#xff1a; 监听用户是否开启权限或关闭权限&#xff1a; 退出app返回桌面&#xff1a; android申请权限&#xff1a; 首先在 manifest.json 内添加你所需要用到权限 添加权限插件 permission.js 一次就好1/权限插件 - Gitee.comhttps://gitee.co…

数据库分库分表中间件选择

目前分库分表的中间件有三种设计思路&#xff0c;分别是&#xff1a; 采用分散式架构&#xff0c;适用于用Java开发的高性能轻量级OLTP应用程序&#xff0c;以Sharding-JDBC为代表。采用中间层Proxy架构&#xff0c;提供了静态输入和所有语言支持&#xff0c;适用于OLAP应用程…