记忆化递归

c++记忆化递归 这有一道题   题目,其实是来源于深基,和洛谷P1028差不多。当然,主要是讲解记忆化递归。 一般的递归,总会面对着超时的风险,比如,在源代码中,sol(2),可能被sol(4)调用,也可能被sol(8)调用,因此做了很多无用功。   为此记忆化递归也是常用的,在动态规划中也是比较常用的。记忆化递归,可以用一个数组,存贮递归过程中计算出的值。当需要再次计算时,直接返回数组的值就可以了。 #include<bits/stdc++.h> using namespace std; int n,f[10 阅读详情

1.情景导入

你应该知道斐波那契数列吧!就是前两项之和等于这一项。如果你学过递归,你肯定会写这道题:输入一个N代表你要求的项数,然后输出斐波那契的第N项。这道题看似简单,实则也挺简单实则特别困难(对于大数据来说)。

下面是一段斐波纳契的代码:

#include <iostream>
using namespace std;
long long f(long long n) {
    if (n < 3){
    	return 1;
	}
	return f(n-1)+f(n-2);
}

int main(){
    long long n;
    cin >> n;
    cout << f(n);
    return 0;
}

 如果我们用C++运行这段代码,你会发现如果我们输入50,它就会加载很久。

肯定会超时!!!!!!!!!!!!!!!!!!!!!!!!!!!!!(っ °Д °;)っ

所以今天我们要学习一种时间复杂度很低的方法!\( ̄︶ ̄*\))

2.导入概念

首先我会向你提出一个问题:是什么原因会导致递归速度这么慢?

如果我们按照计算机的方法去思考, 你会发现重复计算的地方太多了!

大家请看下图:

 在图片上有人计算机的方法给大家演示出来了如果我们要求斐波那契的第五项,计算机内部会是怎样运算.在这么小的例子中居然重复计算了两次斐波那契的第三项,那你想象一下如果斐波那契的项数不断增加求成了五十,重复计算的个数会越来越多,我们这种方法不再重复计算.

大概意思

我们可以用一个数组来递归,一开始数组的一号位和二号位默认为一.如果数组的第N号位有东西,也就是已经计算过了,那之间返回这一号位的值,如果没有,按照原来的方法进行计算(一定要赋值给我们的数组中).

简简单单的动态规划思路,计算过的就不再计算了(❤️ ω ❤️)

代码

直接公布

#include <iostream>
using namespace std;
long long d[100000] = {0,1,1};
long long f(long long n) {
    if (d[n] != 0){
        return d[n];
    }
    return d[n] = f(n-1)+f(n-2);
}

int main(){
    long long n;
    cin >> n;
    cout << f(n);
    return 0;
}

//一定要开long long

3.例题

题目名称:数字三角形

数字三角形,从三角形顶部往下走,只能往左下或右下走,求走到最下面时所经过的数字和最大为多少?(下图为n=6时的情况)

输入描述


第1行:整数n(1<=n<=1000)

第2-n+1行:每行若干整数,第i行有i-1个整数,空格分隔。

输出描述


一行:一个整数,表示所经过数字的最大和。

样例1

输入

6
2
96 30
83 52 60
21 65 44 61
8 79 50 41 21
61 41 50 38 79 10

输出

375

1.先做一遍样例 

从2开始, 96 > 30,83 > 52,65 > 21,79 > 50,50>41;

所以最终的式子是:2+96+83+65+79+50=375

2.思路

这回重复的就是路径,我们会把路径中元素的和储存在一个名字叫做D的数组中,从顶部开始,判断底下两条路径的最大值,调用自身函数进行递归。到达下一个节点再进行求最大值,如果这个节点以前算过那就不算直接返回d的这一号位.

3.代码

#include <bits/stdc++.h>
using namespace std;
int d[1005][1005];
int a[1005][1005];
    int n;
int s(int i, int j){
    if (d[i][j] >= 0){
        return d[i][j];
    }
    return d[i][j] = a[i][j]+(i==n+1?0:max(s(i+1,j),s(i+1,j+1)));
}
int main(){
    cin >> n;
    memset(d,-1,sizeof(d[0][0])*1005*1005);  //初始化设为负一
    for (int i =1; i <= n+1; i++){
        for (int j =1; j < i; j++){
            cin >> a[i][j];
        }
    }
    cout << s(1,1);
    return 0;
}

4.另外一种解法:递推

从底下的每一个节点和往上推,这里就不细讲了。

#include <bits/stdc++.h>
using namespace std;
int d[1005][1005];
int a[1005][1005];
int n;
int main(){
    cin >> n;
    for (int i =1; i <= n+1; i++){
        for (int j =1; j <= i; j++){
            cin >> a[i][j];
        }
    }
    for (int j =1; j <= n; j++){
        d[n][j] = a[n][j];
    }
    for (int i =n; i >= 1; i--){
        for (int j =1; j <= i; j++){
            d[i][j] = a[i][j]+max(d[i+1][j],d[i+1][j+1]);
        }
    }
    cout << d[1][1];
    return 0;
}

 一个彩蛋

Python绘制的好看统计图:Python绘制的好看统计图-优快云博客icon-default.png?t=N7T8https://blog.youkuaiyun.com/pythonwyw123321/article/details/138375045?spm=1001.2014.3001.5502

 大家可以看一看我的这篇博客,大概效果会有一个弹窗出现里面有很多好看的统计图,像bug一样.

 

C++ 递归函数 详细解析——C++日常学习随笔 1. 递归函数 1.1 递归函数的定义 递归函数:即在函数体中出现调用自身的函数,即函数Func(Type a,……)直接或间接调用函数本身; 递归函数:在数学上,关于递归函数的定义如下:对于某一函数f(x),其定义域是集合A,那么若对于A集合中的某一个值x0,其函数值f(x0)由f(f(x0))决定,那么就称f(x)为递归函数; 递归函数:不能定义为内联函数; 阅读详情

相关推荐

Labelme AI-Polygon闪退排查与修复指南

本文详细介绍了Labelme AI-Polygon功能闪退问题的排查与修复方法,包括环境配置检查、模型路径设置、依赖库版本控制等关键步骤。通过系统性的解决方案和实用技巧,帮助用户快速解决闪退问题,确保数据标注工作的高效进行。

weixin_29311017的博客 140

递归学习——记忆化搜索

关于记忆化搜索的几道题。

qq_41934502的博客 1586

flash均衡磨损--实时保存设备数据

【代码】flash均衡磨损--实时保存设备数据。

Car12 480

记忆化递归(记忆化搜索)

前言 ​ 前一篇博客写到入门的dp算法,后来又遇到一个奇怪的变种题目,同样也是可以用dp写的(至少标签是有动态规划)。我看了答案还是有些不能完全理解,于是又去b站翻了翻教程基础DP,其中提到记忆化的递归(也称记忆化搜索),相当于结合了dp和递归的优点(这时我又觉得比DP还厉害),然后就准备写写记忆化递归。 目录 ​ 1.记忆化递归的解释与分析 ​ 2.记忆化递归的应用 一、记忆化递归的解释与分析 前面说道它结合了dp和递归的优点,分别是记忆化和逻辑清晰易懂。 下面还是结合斐波那契数列的来理解: F(.

humour_man的博客 2086

手把手教你学 MATLAB 实战训练(6.9):卷积神经网络(CNN)模型来进行图像分类任务(预训练的 ResNet-50 模型)

加载数据集数据预处理加载预训练模型修改和扩展预训练模型设置训练选项训练模型测试模型。

xiaoheshang_123的博客 647

【100分】【等和子数组最小和】

逆序排序,这样能够使得在分组时优先选取较大的元素,以便将元素分配到较小的子集中,从而使得每个子集的和相对均衡。给定一个数组nums,将元素分为若干个组,使得每组和相等,求出满足条件的所有分组中,组内元素和的最小值。分成若干个组,使得每组的和相等,并求出满足条件的所有分组中,组内元素和的最小值。在递归的过程中,我们需要注意一个优化点,即避免将相同和的桶重复计算。4 个子集(5),(1,4),(2,3),(2,3)2 个子集(5, 1, 4),(2,3, 2,3)个子集,则返回子集和的最小值,如果不能,则将。

weixin_54707168的博客 1169

python 递归、记忆化递归、递归法模板

1、至少有一个明确的递归结束条件;2、给出递归终止时的处理办法;3、每次进入更深一层递归时,问题规模(计算量)相比上次递归都应有所减少。

m0_59553037的博客 1334

Unity之OpenXR+XR Interaction Toolkit接入HTC Vive

目前VR领域,最流行的设备要当属HTC VIVE了。以前在Unity端接入HTC VIVE设备时,都是通过SteamVR+VRTK来接入的。但是随着Unity的版本升级和OpenXR标准的流行,再加上VR设备的逐渐增多。SteamVR+VRTK的方式已经无法更好的满足大家的需求。

TxNet 4140

记忆化递归例题——斐波那契数列

记忆化搜索 我们在搜索的时候可能会重复搜索,这样程序不会高效处理一个问题,我们可以每次将该次的搜索保存,当再一次搜索到这时,我们就可以不必继续搜索,将该次搜索的值返回,于是这次搜索被跳过,继续往下搜索 比如利用递归求斐波那契数列的第N项值 #include<iostream> using namespace std; int op(int n) { if(n==1||n==2) return 1; return op(n-1)+op(n-2); } int main() { int n;

一个无聊的程序猿 3563

【PX4学习笔记】3. PX4 固件烧写(1 探索过程)

飞控型号:cube orange【PX4官方用户指南中关于cube orange的描述】 飞控载板型号:Mini Carrier Board【迷你载板说明文档】 固件安装参考:The Cube User Manual V1.0

【人工智障 | 计算鸡视觉 | 机器孩】 7677

Innovus: dbGet 快速学习教程

是取反的意思,如下例子,这个选中的instance一共四个pin,当用regexp筛选CK pin后只获得CK pin,加上-v取反后就返回的值就是除CK pin以外的其他三个pin。dbGet有很多option,具体都是干嘛的,怎么用,做个简单介绍。,-p是最常用的option,-p和-p0 -p1是一个东西,-p x它代表从后往前推第x个选项,与-p搭配使用的pattern也是必须的。的意思是返回database整数,而一般我们用的是浮点数,database整数可以参考DEF里的单位去输出。

m0_61544122的博客 6961

Koltin 递归、尾递归和记忆化

文章目录1. 递归与尾递归1.1 尾递归(tail call)1.2 递归1.3 递归和尾递归的区别2. 尾递归消除2.1 尾调用消除 学习秒表: 了解 Kotlin 中的尾递归函数 从 尾递归 了解 fold、foldRight、 reverse 等实现 为什么用递归来代替for循环 实现记忆化 1. 递归与尾递归 Kotlin 中很好的支持递归函数,使得递归可以被广泛使用, 但是稍微了解算法的人都知道, 递归函数一不小心就会爆栈,即随着递归次数的增加,内存不足以存储中间的计算步骤和中间结果,导致内存

RikkaTheWorld 2179

13、7自由度机械臂混合逆运动学算法解析

本文介绍了一种针对7自由度机械臂的混合逆运动学算法,通过引入额外参数Φ解决冗余自由度问题,并实现了避障、避免关节超限和扩大工作空间。该方法采用解析逆运动学求解策略,克服了机械臂在奇异位姿时的配置不连续性问题。通过对比实验验证了该算法在腕部关节角度连续性和位姿可达性方面的优越性,同时结合躯干逆运动学显著扩展了机械臂的工作空间。

rgv23456789的博客 238

记忆化递归入门

圆环套圆环 (知识点:记忆化递归) 题目 题目描述: 一个有趣的圆环套圆环函数被定义如下: G(n)=n-G(G(n-1)) (n是正整数) G(0)=0 请你计算出圆环函数的值。 输入: 一个非负整数n,n<=200。 输出: 一个正整数,即G(n)。 第一次提交 (时间超限83) #include<bits/stdc++.h> using namespace std; int a(int k) { if(k==0) return 0; return k-a

Wu_yongtao的博客 1813

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

记忆化递归问题

记忆化递归

weixin_41399650的博客 576

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

递归+记忆化搜索

上台阶 题目描述  现在小瓜想走上一个一共有n级的台阶,由于小瓜的腿比较短,他一次只能向上走1级或者2级台阶。小瓜想知道他有多少种方法走上这n级台阶,你能帮帮他吗? 输入 一行一个整数n(n<=100000),表示一共有n级台阶。 输出 一行一个整数,表示小瓜上台阶的方案数对100003取余的结果。   输入样例 3 输出样例 3   分析  我们采用递归的算法 代码1: 计算原理:sum(...

春江花朝秋月夜 433

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【递归、搜索与回溯】记忆化搜索

【递归、搜索与回溯】记忆化搜索

fight_p的博客 2276

【递归、搜索与回溯算法】记忆化搜索

本篇文章列举了五个经典的LeetCode算法题目,包括斐波那契数、不同路径、最长递增子序列、猜数字大小 II和矩阵中的最长递增路径。我会在每道题中提到每道题的解题思路,并提供解决本题的C++代码。

是阿建吖! 1330

递归-记忆化搜索

有关递归记忆化搜索的文章,主要给自己的看的

qq_37448192的博客 722

递归算法优化写法,记忆化递归

举例 一个数从0开始,依次累加 每次可以加1或者2,到n的话有多少种累加方法 如 1=0+1 【1种】 2=0+1+1或0+2 【2种】 3=0+1+1+1或0+1+2或0+2+1 【3种】 4=0+1+1+1+1或0+1+1+2或0+1+2+1或0+2+1+1或2+2 【5种】 5=0+1+1+1+1+1或0+1+1+1+2或0+1+1+2+1或0+1+2+1+1或0+2+1+1+1或0+2+1+2或0+2+2+1或0+1+2+2 【8种】 。。。 总结算式

【03】的博客 611

递归(详解+记忆化递归)

递归 一.递归三大要素 1.明确这个函数想要干什么 函数的功能; 2.寻找递归的结束条件 找到递归的参数为什么时,递归结束; 3.找出函数的等价关系式 不断缩小参数的范围,例如Factorial数列; 二.递归思想 所有递归的代码都类似,基本上都是有一个基线条件和一个递归条件; 基线条件(递归出口):指的是函数不在调用自己,从而避免无限循环; 递归条件(递归调用):函数调用自己; 伪代码如下: i...

weixin_45843077的博客 2023

什么是记忆化递归?

摘要: 记忆化递归是一种通过缓存子问题结果来优化递归算法的技术,采用空间换时间策略,将指数级时间复杂度降为多项式级。其核心实现包括检查缓存、处理递归基、存储计算结果三个步骤,适用于斐波那契数列、组合数计算等重叠子问题场景。与动态规划相比,记忆化递归采用自顶向下方式,而动态规划为自底向上。优化时需注意缓存结构选择、空间效率及递归深度问题。典型应用包括爬楼梯、最长公共子序列等算法问题,能显著提升递归效率但需合理管理缓存以避免栈溢出或空间浪费。

qq_39980997的博客 327

总结——递归、记忆化搜索、递归

递归函数运行时分为函数 前进段 和 返回段 ,真正明白并时刻记住这个才真正掌握了递归。    写递归时三点:开始定义的参数,结束条件(边界)(若干if语句),递归调用及返回段运算。 ·一般参数中总有一个代表递归层数。 ·递归结束返回时要考虑是否修改了全局变量,并将其改回,这个是为回溯做准备。记忆化搜索:解决了递归时大量的重复计算(通过将每次计算值记录入数组)本质:空间换时间。递推:推出公式。(感觉

319
上一篇: 二分查找做的小游戏
下一篇: Python绘制的好看统计图
B757-300
博客等级 码龄4年 259粉丝 52原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值