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

目录

递归的介绍

递归如何实现

递归和循环的比较

例题:

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

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

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

(二、数的计算)

(三、计算函数值)

解题思路


递归的介绍

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

递归如何实现

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ttkefu在线客服如何获取代码

注册并登录ttkefu账号。可以在ttkefu的官方网站&#xff08;https://www.ttkefu.com/&#xff09;上进行注册和登录。下载并安装ttkefu的PC端软件。可以在官方网站上的下载页面&#xff08;https://www.ttkefu.com/download.html&#xff09;找到下载链接。在软件中获取代码。登…

算法中栈的应用

目录 栈 练习1&#xff1a;删除字符串中的所有相邻重复项 练习2&#xff1a;比较含退格的字符串 练习3&#xff1a;基本计算器II 练习4&#xff1a;字符串解码 栈 栈 是一种常见的数据结构&#xff0c;遵循先进后出&#xff08;LIFO&#xff09;的原则&#xff08;最后进入…

Linux系统:内核参数调优

目录 1、/proc目录 2、sysctl命令 3.1 控制源路由验证 3.2 控制内核的系统请求调试功能 3.3 控制核心转储是否将PID附加到核心文件名 3.4 控制TCP同步cookie的使用 3.5 在网桥上禁用netfilter 3.6 控制消息队列的默认最大大小 3.7 调试TCP内核参数 3.8 调试套…

解读:DUSt3R: Geometric 3D Vision Made Easy

概述&#xff1a;给定一个无约束图像集&#xff0c;即一组具有未知相机姿态和内在特征的照片&#xff0c;我们提出的 DUSt3R 方法会输出一组相应的点阵图&#xff0c;从中我们可以直接恢复通常难以一次性估算的各种几何量&#xff0c;如相机参数、像素对应关系、深度图和完全一…

微信小程序-2

数据绑定 index.js Page({data: {info: hello world,randomNumber: Math.random() * 10,imgSrc:http://www.itheima.com/images/logo.png} })index.wxml <view>{{ info }}</view><view>{{ randomNumber > 5 ? 随机数大于等于5 : 随机数小于5 }}</v…

HarmonyOS—HAP唯一性校验逻辑

HAP是应用安装的基本单位&#xff0c;在DevEco Studio工程目录中&#xff0c;一个HAP对应一个Module。应用打包时&#xff0c;每个Module生成一个.hap文件。 应用如果包含多个Module&#xff0c;在应用市场上架时&#xff0c;会将多个.hap文件打包成一个.app文件&#xff08;称…

JeecgBoot Vue3前端项目性能优化按需加载方案

JeecgBoot vue3前端项目在 3.5.5 版本之前&#xff0c;的确存在很严重的性能问题&#xff0c;大家可以参考以下文档进行升级。 按需加载改造方法 1、全局注册地方去掉2、组件改成异步注册3、用不到的大组件可以删掉 【精简项目方案】 大组件 1、富文本 tinyme2、Markdown3、…

深度学习算法优化流程

深度学习算法的一般优化流程&#xff0c;具体的实施方法和步骤可能会根据具体任务和数据的特点而有所不同&#xff0c;优化流程通常包括以下几个主要步骤&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作…

中文文本分类_1(pytorch 实现)

import torch import torch.nn as nn import torchvision from torchvision import transforms, datasets import os, PIL, pathlib, warningswarnings.filterwarnings("ignore") # 忽略警告信息# win10系统 device torch.device("cuda" if torch.cuda.i…

(1)预处理

我们需要的文件结构如上 main.cpp add.h add.cpp add.h 这里使用riscv的工具链编译为.i文件&#xff0c;需要使用-E&#xff0c;就是只进行预处理&#xff0c;我们可以得到两个.i文件即main.i和add.i main.i 这里看到main.i里头文件全部替换&#xff0c;然后多了三万多行 所以…

【C++第三课 - 类和对象中】构造函数、析构函数、拷贝构造函数

目录 类的6个默认成员函数构造函数自己写的构造函数默认生成的构造函数 析构函数概念特征 拷贝构造函数特征 运算符重载 、 >、 < 赋值重载Date类的完善构造函数的完善用复用 类的6个默认成员函数 默认成员函数&#xff1a;不写编译器也会默认生成一份 构造函数 自己…

uniapp制作--简单的tab切换

一、实现思路 在UniApp中&#xff0c;可以使用v-if来控制Tab栏并进行切换。 创建一个方法来控制点击时的效果。 二、实现步骤 ①view部分展示 <!-- tab选项 --><view class"select-area"><view class"select-top"><view clas…

恒创科技2024开年采购海外服务器配置及价格汇总

喜迎龙年&#xff0c;开年采购开好局。值企业开工采购浪潮来袭之际&#xff0c;为进一步满足个人开发者到中小企业等各类型用户的选购需求&#xff0c;中国香港及亚太数据中心领先服务商恒创科技启动了“ 2024 开年采购开好局”大促活动&#xff0c;该活动已于 3 月 5 日正式上…

消费品亚马逊化学测试要求有哪些?RSL,双酚A(BPA)REACH,CPSIA等

消费品亚马逊化学测试要求有&#xff1a;RSL&#xff0c;双酚A&#xff08;BPA&#xff09;REACH&#xff0c;CPSIA&#xff0c;加州65&#xff0c;等 亚马逊对所有在其官方网站上架产品的化学物质和重金属限制&#xff0c;以及亚马逊如何检查符合欧盟和美国的消费品法规中的第…

【科研基础】插图摘录

FedSL: Federated Split Learning for Collaborative Healthcare Analytics on Resource-Constrained Wearable IoMT Devices Blockchain-Based Trustworthy and Efficient Hierarchical Federated Learning for UAV-Enabled IoT Networks

langchain学习笔记(十一)

关于langchain中的memory&#xff0c;即对话历史&#xff08;message history&#xff09; 1、 Add message history (memory) | &#x1f99c;️&#x1f517; Langchain RunnableWithMessageHistory&#xff0c;可用于任何的chain中添加对话历史&#xff0c;将以下之一作为…

怎么采集GBK或GB2312等特殊字符编码的网站数据

如果要采集的网站是GBK或GB2312等特殊字符编码&#xff0c;采集结果可能是一堆看不懂的文字或乱码&#xff0c;无法使用。 通常网页文章采集工具有字符编码选项&#xff0c;默认是UTF-8&#xff08;现在大部分网站都是&#xff09;&#xff0c;改选为GBK或GB2312字符编码即可&…

c++数据结构算法复习基础-- 3 --线性表-单向链表-笔试面试常见问题

1、单链表逆序 思路图 代码实现 //著: 链表结构里记得加 friend void ReverseLink(Clink& link); void ReverseLink(Clink& link) {Node* p link.head_->next_;while( p nullptr){return;}Node* q p->next_;link.head_->next_ nullptr;while(p ! nullpt…

Java解决杨辉三角

Java解决杨辉三角 01 题目 给定一个非负整数 *numRows&#xff0c;*生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRo…

亚信安慧AntDB:编织数据丝路,缔造创新篇章

亚信安慧AntDB作为一款具备国产化升级改造经验的数据库系统&#xff0c;在15年的平稳运行中积累了丰富经验。通过持续的创新和技术进步&#xff0c;AntDB不断优化性能和功能&#xff0c;满足用户的需求&#xff0c;与国际先进数据库系统保持竞争力。 AntDB秉承着与用户和行业保…