算法27:从暴力递归到动态规划(1)

news2025/1/12 1:00:31

题目:已知数列的规则为 1 1 2 3 5 8 13 21 ..... * 按照这种规则,求第n项, n > 2.

这是典型的斐波拉切数列, 公式为 F(n)=F(n - 1)+F(n - 2)

 那么就可以推导出

 F(n)=F(n - 1) + F(n - 2)

F(n-1)=F(n - 2) + F(n - 3)

 F(n-2)=F(n - 3) + F(n - 4)

F(3)=F(n - 4) + F(n - 25)

..........

F(3)=F(2)+F(1) 

递归代码:

   public static int func (int n)
    {
        if (n == 1 || n == 2) {
            return 1;
        }
        return func(n-1) + func(n-2);
    }

下面看一张图:

 我们发现,每一次递归的过程中,都会存在大量的重复推算过程。比如 f(n-3)这个函数,在一次 f(n)的计算中,就重复的被推算了很多次。 因此,如果我们每一次递归的时候,把已经推算出来的结果存在缓存中,如果出现重复推算的函数,我们直接获取到对应的值,那么执行的时间会得到优化,优化代码如下:

动态规划初级版本


    //动态规划_初级版
    public static int value (int n)
    {
        if (n == 1 || n == 2) {
            return 1;
        }
        int[] dp = new int[n];
        for (int i = 0; i < dp.length; i++) {
            dp[i] = -1;
        }
        int result = func2 (n, dp);
        return result;
    }

    public static int func2 (int n, int[] dp)
    {
        int index = n - 1;
        if (dp[index] != -1) {
            return dp[index];
        }

        int result;
        if (n == 1 || n == 2) {
            //数组是从0开始的, 比如f(3)中的3应该在数组的下标2处
            result = 1;
        }
        else {
            result = func2(n-1, dp) + func2(n-2, dp);
        }
        dp[index] = result;
        return result;
    }

 

其实,到目前为止,代码已经优化完毕了,我们发现相同函数在一次递归中只会计算一次,重复出现会直接从缓存数组中拿到。 

现在我们发现,在计算 f(n) 的时候,从f(1).......f(n-1)都要递归计算一遍。递归浪费时间、缓存浪费空间。而缓存+递归的方式,时间得到了改进,但是空间却损失了一部分,但是整体代码是得到了优化的。那么我们试想一下,如果我们直接采用空间换时间的思想,是否会走向另一个极端呢?这就引申出一个新的概念,动态规划。

动态规划代码

  public static int func3 (int n)
    {
        if (n == 1 || n == 2) {
            return 1;
        }
        int[] dp = new int[n];
        dp[0] = 1;
        dp[1] = 1;

        for (int i = 2; i < dp.length; i++) {
            dp[i] = dp[i-1] + dp[i-2];
        }
        //数组下标从0开始,因此需要减 n-1
        return dp[n-1];
    }

 动态规划采用的是空间换时间的概念,反正前面的所有值都要推导一遍,那么直接推导出结果放入缓存,从缓存中拿到也是一样的。

本题只是一个入门,可能很多人都会觉得采用 递归+动态规划的思想更好。其实,任何程序的设计都要考虑到系统环境的。递归、递归+动态规划、纯动态规划,要根据自己的实际环境进行选择

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

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

相关文章

Spring Boot 如何处理国际化

Spring Boot 国际化 在全球化的今天&#xff0c;很多应用程序需要支持多种语言和地区。为了满足不同用户的需求&#xff0c;应用程序需要提供多语言的支持。Spring Boot 提供了强大的国际化支持&#xff0c;使得开发人员能够轻松地为应用程序添加多语言支持。本文将介绍如何使…

chatgpt赋能Python-python_id用法

Python ID用法介绍 在 Python 编程中&#xff0c;ID 是一个极其重要的概念。ID 是一个对象在内存中的唯一标识符&#xff0c;每个对象都有一个唯一的 ID。在本文中&#xff0c;我们将介绍 Python ID 的用途和用法&#xff0c;并且给出一些示例&#xff0c;以帮助读者更好地理解…

lab4:以time/gettimeofday系统调用为例分析ARM64 Linux 5.4.34

一、ARM64 Linux系统调用过程 &#xff08;1&#xff09;svc指令触发系统调用。 &#xff08;2&#xff09;保存现场&#xff08;el0_sync处的内核汇编代码保存异常发生时程序的执行现场&#xff09;&#xff0c;然后根据异常发生的原因&#xff08;ESR_EL1寄存器&#xff09;…

“不务正业”的奶茶店三个月实现30+万收入

今天我和大家分享一个 我身边的案例。 我有一个朋友 和我分享他朋友的 一个奶茶店 互联网商城的故事。 19年李某开了一家 奶茶店&#xff0c;同时呢 自己在平台做了一个 线上购买奶茶的商城 他是怎么做的呢&#xff1f; 原来每次有客户来到店 购买奶茶的时候。 他会和客户说 扫…

BetaFlight Mark4 H7 Dual270 + BN880 + CRSF 配置存档

BetaFlight Mark4 H7 Dual270 BN880 CRSF 配置存档 1. 源由2. 配置2.1 端口2.2 系统2.3 对齐2.4 GPS2.5 救援2.6 PID2.7 Rate2.8 滤波2.9 接收器2.10 模式2.11 电机 3.差异4. 整机效果5. 飞行效果6. 参考资料 1. 源由 手头这台航模四轴&#xff0c;基本调试的差不多&#xf…

【数据分析之道-Numpy(八)】numpy统计函数

文章目录 专栏导读1、np.mean()2、np.median()3、np.std()4、np.var()5、np.min()6、np.max()7、np.sum()8、np.prod()9、np.percentile()10、np.any()11、np.all() 专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN Python领域新星创作者&#xff0c;专注于分享python领…

Qt QGenericPlugin插件使用案例

问题描述: Qt插件的编写,有两种方式,一种是直接通过自定义接口类Interface来实现,一种是通过QtCreator自带的插件模板来创建。 这里我们先来实现第二种。 功能为点击主界面的按钮,显示插件界面。(插件和开发库一样,什么都可以放进去,只不过就是封装成方便调用的模块…

Vue|非单文件组件

传统网页一些不可避免的小问题: 1.网页JS、CSS等资源依赖关系混乱,不方便维护 2.代码复用率很低 使用组件将代码进行复用,简化项目结构,提高运行效率,便于维护 组件定义传统网页组件 传统代码实现步骤 组件代码定义组件注册组件局部注册全局注册 使用组件避坑 组件定义 组件即为…

聊聊如何利用spring插件来实现策略模式

前言 偶然的机会发现spring有个spring-plugin&#xff0c;官网对它的介绍是 Spring Plugin provides a more pragmatic approach to plugin development by providing the core flexibility of having plugin implementations extending a core system’s functionality but o…

linux上使用系统安装和Docker安装mysql的两种方式

一、安装到linux 1、安装mysql-server 1、在安装之前查看下系统是否已经安装了mysql ls /usr/share2、安装mysql-server sudo apt-get install mysql-server3、再次查看&#xff0c;发现多了个mysql ls /usr/share | grep mysql //在ls打印结果中搜索mysql关键字4、登陆 在…

chatgpt赋能Python-python_lamb

Python Lambdas - 强大的匿名函数 Python是一个充满了强大特性的编程语言&#xff0c;其中之一就是Python的lambda函数。在这篇文章中&#xff0c;我们将介绍Python lambdas的基础知识、使用方法、优缺点以及与普通函数的区别。 什么是Python Lambda函数 Python Lambda函数&…

咖啡「江湖」:从1999到2023

【潮汐商业评论/原创】 “我现在几乎每天都要来杯咖啡&#xff0c;哪怕周末在家休息也是。上班喝美式是为了提神&#xff0c;在家做拉花是享受生活&#xff0c;平时和朋友出去大概率还是会选择咖啡馆&#xff0c;毕竟看起来有氛围还不发胖。”Allen说道。 事实上&#xff0c;…

地铁车辆项目RAMS管理

导读 由于RAMS管理可以为轨道交通提供安全保障&#xff0c;提高运行效率&#xff0c;该管理模式在国外已得到广泛应用&#xff0c;并取得了良好成效。因此引入RAMS管理是确保城市轨道交通车辆安全发展的必然趋势。本文分析地铁车辆项目RAMS管理的必要性&#xff0c;阐述了项目各…

不要做一个透明人:展现真实的自己

✨求关注~ &#x1f600;博客&#xff1a;www.protaos.com 目录&#xff1a; 引言&#xff1a;透明人的困境透明人的定义与特征 2.1 透明人的追求与代价 2.2 社交媒体与透明人现象的关系透明度的局限性 3.1 自我保护与隐私权 3.2 虚假的透明度和个人形象管理重建真实的自我 4.…

城市内涝的原因和解决措施,内涝监测预警助力城市防涝度汛

城市内涝是城市化进程中最遇到的自然灾害&#xff0c;城市内涝不仅会对市民生活造成困扰&#xff0c;也会对城市基础设施和经济发展产生不利影响。因此&#xff0c;及时监测城市内涝现象&#xff0c;对于城市管理和城市安全具有重要意义。本文将深入探讨城市内涝的原因以及针对…

docsify安装(线上文档)

01、docsify 是什么 一款神奇的文档生成利器 自从有了 Markdown&#xff0c; 我就再没用过富文本编辑器&#xff0c;因为 Markdown 的书写有一种心流的感觉。很多博客平台都支持 Markdown 了&#xff0c;即便是不支持&#xff0c;也没关系&#xff0c;可以通过 mdnice 或者 Md…

亚马逊云科技推出全新即用型模型,通过机器学习在几分钟内生成见解

4月10日&#xff0c;亚马逊云科技宣布推出Amazon Amazon SageMaker Canvas中的新功能&#xff0c;这些功能可帮助业务分析师通过机器学习&#xff08;ML&#xff09;在几分钟内从数千个文档、图像和文本行中生成见解。新功能推出后&#xff0c;可以访问即用型模型&#xff0c;创…

六、数据仓库详细介绍(ETL)工具篇下

0x00 前言 上篇&#xff0c;我们介绍了五种传统 ETL 工具和八种数据同步集成工具。 数据仓库详细介绍&#xff08;五.ETL&#xff09;工具篇上 本篇&#xff0c;我们接着介绍两种新型 ETL 工具、大数据发展不同阶段产生的六种主要计算引擎、五种流程控制组件。 最后我们简单…

空间转换案例-3D导航

想要制作这么一个简单的 3D 导航栏需要了解以下几个知识 : 1.空间转换 : 从坐标轴角度除了我们熟知的 X , Y 外还会和 Z 坐标轴 构成一个立体空间, Z轴的位置与我们眼睛视线的方向相同. 空间转换的属性仍然是 transform ,所以可以给他添加 空间的 平移,旋转,缩放 等效果. 2.空…

[问]python中字典dict如何排序sorted?

文章目录 一、sorted使用二、按照keys的顺序对dict中的keys排序三、按照valuse的顺序对dict中的values排序四、按照keys的顺序对dict中的items排序五、按照values的顺序对dict中的items排序六、按照keys的顺序对dict的values排序七、按照values的顺序对dict中的keys排序八、字典…