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

目录

递归的介绍

递归如何实现

递归和循环的比较

例题:

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

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

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

(二、数的计算)

(三、计算函数值)

解题思路


递归的介绍

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

递归如何实现

递归函数的基本结构如下:
返回类型 函数名(参数列表){基本情况(递归终止条件)
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.rhkb.cn/news/266639.html

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

相关文章

Python+Selenium+Unittest 之Unittest1--简介

Unittest属于是一种单元测试框架&#xff0c;主要用于对代码中写好的单元内容进行验证&#xff0c;比如写好一个函数&#xff0c;可以使用unittest去进行验证该函数的代码逻辑是否有问题&#xff0c;对于自动化来说&#xff0c;可以去检验每条用例的内容是否符合预期。 Unittes…

ChatGPT在测试计划中的应用策略

测试计划是指描述了要进行的测试活动的范围、方法、资源和进度的文档。它主要包括测试项、被测特性、测试任务和风险控制等。 所以在使用ChatGPT输出结果之前&#xff0c;我们需要先将文档的内容框架梳理好&#xff0c;以及将内容范围划定好&#xff0c;必要的时候&#xff0c…

vue实现自定义树形穿梭框功能

需求&#xff1a; 我们在开发过程中&#xff0c;会遇到需要将一个数据选择做成穿梭框&#xff0c;但是要求穿梭框左侧为树形结构、右侧为无层级结构的数据展示&#xff0c;ElementUI自身无法在穿梭框中添加树形结构&#xff0c;网上搜到了大佬封装的插件但是对于右侧的无树形结…

Socket网络编程(一)——网络通信入门基本概念

目录 网络通信基本概念什么是网络&#xff1f;网络通信的基本架构什么是网络编程?7层网络模型-OSI模型什么是Socket&#xff1f;Socket的作用和组成Socket传输原理Socket与TCP、UDP的关系CS模型(Client-Server Application)报文段牛刀小试&#xff08;TCP消息发送与接收&#…

vulnhub-----Hackademic靶机

文章目录 1.C段扫描2.端口扫描3.服务扫描4.web分析5.sql注入6.目录扫描7.写马php反弹shell木马 8.反弹shell9.内核提权 1.C段扫描 kali:192.168.9.27 靶机&#xff1a;192.168.9.25 ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0,…

11.以太网交换机工作原理

目录 一、以太网协议二、以太网交换机原理三、交换机常见问题思考四、同网段数据通信全过程五、跨网段数据通信全过程六、关键知识七、调试命令 前言&#xff1a;在网络中传输数据时需要遵循一些标准&#xff0c;以太网协议定义了数据帧在以太网上的传输标准&#xff0c;了解以…

苹果iOS群控系统开发常见功能及其代码解析!

随着移动互联网的快速发展&#xff0c;iOS设备因其良好的用户体验和丰富的应用生态&#xff0c;受到了广大用户的喜爱&#xff0c;苹果iOS群控系统&#xff0c;即可以同时对多台iOS设备进行集中控制和管理的系统&#xff0c;逐渐成为了开发者、测试人员以及企业管理的有力工具。…

解析馆藏文物预防性保护:监测平台与数据传输系统概述

1&#xff09;文物预防性保护监测平台概述 文物预防性保护监测与调控系统是文物环境监测必不可少的关键组成部分之一,在项目实施中,将充分利用前沿物联网技术&#xff0c;如无线网络、低功耗设计、高精度传感器来实现文物保存环境的实时监测与数据分析。此外&#xff0c;还将通…

php基础学习之错误处理(其二)

在实际应用中&#xff0c;开发者当然不希望把自己开发的程序的错误暴露给用户&#xff0c;一方面会动摇客户对己方的信心&#xff0c;另一方面容易被攻击者抓住漏洞实施攻击&#xff0c;同时开发者本身需要及时收集错误&#xff0c;因此需要合理的设置错误显示与记录错误日志 一…

SpringMVC 学习(七)之报文信息转换器 HttpMessageConverter

目录 1 HttpMessageConverter 介绍 2 RequestBody 注解 3 ResponseBody 注解 4 RequestEntity 5 ResponseEntity 6 RestController 注解 1 HttpMessageConverter 介绍 HttpMessageConverter 报文信息转换器&#xff0c;将请求报文&#xff08;如JSON、XML、HTML等&#x…

android移动应用开发答案第二版,Kafka是如何实现高性能的

面试官&#xff1a;说说什么是 UI 线程&#xff1f; A&#xff1a;就是用来刷新 UI 所在的线程嘛 面试官&#xff1a;多说点 A&#xff1a;UI 是单线程刷新的&#xff0c;如果多个线程可以刷新 UI 就无所谓是不是 UI 线程了&#xff0c;单线程的好处是&#xff0c;UI 框架里…

一个Web3项目的收官之作,必然是友好的用户界面(Web3项目三实战之四)

正如标题所述,一个对用户体验友好的应用,总是会赢得用户大加赞赏,这是毋庸置疑的。 甭管是web2,亦或是已悄然而至的Web3,能有一个外观优美、用户体验效果佳的的界面,那么,这个应用无疑是个成功的案例。 诚然,Web3项目虽然核心是智能合约攥写,但用户界面也是一个DApp不…

程序员的金三银四求职宝典

随着春天的脚步渐近&#xff0c;对于许多程序员来说&#xff0c;一年中最繁忙、最重要的面试季节也随之而来。金三银四&#xff0c;即三月和四月&#xff0c;被广大程序员视为求职的黄金时期。在这两个月里&#xff0c;各大公司纷纷开放招聘&#xff0c;求职者们则通过一轮又一…

性能】JDK和Jmeter的安装与配置

一、JDK环境配置 1. 下载JDK 官网下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html 选择对应系统的安装包&#xff0c;下载后安装&#xff0c;安装中记录JDK安装的地址&#xff0c;之后一直点击下一…

VuePress + GitHub 搭建个人博客踩坑记录

最近想给我教练搭个网站,本来选的是 VuePress 框架,也折腾完了,起码是搭建出来了,踩的坑也都总结好了 但是最近发现了一个更简洁的模板: VuePress-theme-hope ,所以最终网站使用的样式是这个 不过我觉得这里面踩坑的记录应该还是有些价值的,分享出来,看看能不能帮到一些小伙伴~…

大数据分析案例-基于SVM支持向量机算法构建手机价格分类预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

Softmax 回归 + 损失函数 + 图片分类数据集【动手学深度学习v2】李沐动手学深度学习课程笔记

目录 Softmax回归 损失函数 图片分类数据集 Softmax回归从零开始实现 Softmax回归简洁实现 Softmax回归 回归和分类的区别 回归问题举例上节课的预测房价问题&#xff0c;分类问题就是对样本进行分类 回归和分类的具体区别 假设真实的类别为第i个类别&#xff08;值为1&#x…

RK3568 Android12 适配抖音 各大APP

RK3568 Android12 适配抖音 各大APP SOC RK3568 system:Android 12 平台要适配抖音和各大APP 平台首先打开抖音发现摄像头预览尺寸不对只存在右上角,我将抖音APP装在手机上预览,发现是全屏 一开始浏览各大博客 给出的解决方法是修改framework 设置为全屏显示: framewo…

android移动应用开发基础答案,安卓工程师面试题

一线企业的app都是多线程和多进程的&#xff0c;而Android进程间通信机制就是Binder&#xff0c;原生的线程间通信则是Handler&#xff0c;Binder和Handler是了解安卓运行机制必须要掌握的一个知识点&#xff0c;更是一线企业面试必问的知识点&#xff01; 以下几道就是大厂关于…

谷歌seo推广秒收录怎么做?

谷歌SEO推广秒收录想要做到&#xff0c;可以利用我们光算科技独家技术&#xff0c;GSI快速收录&#xff0c;通过技术手段和操作&#xff0c;帮你的网站快速被谷歌发现和记录 这项技术具体核心就是GPC爬虫池系统&#xff0c;这个系统是专门研究谷歌搜索引擎优化的规律和算法创造…