【算法刷题 | 动态规划01】5.01(动态规划理论基础、斐波那契数、爬楼梯、使用最小花费爬楼梯)

news2024/11/20 8:42:50

在这里插入图片描述

文章目录

  • 1.动态规划理论基础
    • 1.1题目分类大纲
    • 1.2什么是动态规划?
    • 1.3背包问题
    • 1.4解题步骤
    • 1.5动态规划应该如何debug?
  • 2.斐波那契数
    • 2.1题目
    • 2.2解法:动态规划
      • 2.2.1动态规划思路
        • (1)确定dp数组以及下标的含义
        • (2)确定递推公式
        • (3)dp数组初始化
        • (4)确定遍历顺序
        • (5)举例推导dp数组
      • 2.2.2代码实现
  • 3.爬楼梯
    • 3.1题目
    • 3.2解法:动规
      • 3.2.1动规思路
        • (1)确定dp数组以及下标的含义
        • (2)确定递推公式
        • (3)dp数组初始化
        • (4)确定遍历顺序
        • (5)举例推导dp数组
      • 3.2.2代码实现
  • 4.使用最小花费爬楼梯
    • 4.1题目
    • 4.2解法:动规
      • 4.2.1动规思路
        • (1)确定dp数组以及下标的含义
        • (2)确定递推公式
        • (3)dp数组初始化
        • (4)确定遍历顺序
        • (5)举例推导dp数组
      • 4.2.2代码实现

1.动态规划理论基础

1.1题目分类大纲

img

1.2什么是动态规划?

  • 动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。
  • 所以动态规划中每一个状态一定是由上一个状态推导出来的这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的,

1.3背包问题

  • 例如:有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

  • 动态规划中dp[j]是由dp[j-weight[i]]推导出来的,然后取max(dp[j], dp[j - weight[i]] + value[i])。

但如果是贪心呢,每次拿物品选一个最大的或者最小的就完事了,和上一个状态没有关系

所以贪心解决不了动态规划的问题。

1.4解题步骤

将动态规划问题拆解为如下五部曲:

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

1.5动态规划应该如何debug?

  • 找问题的最好方式就是把dp数组打印出来,看看究竟是不是按照自己思路推导的!

  • 做动规的题目,写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍,心中有数,确定最后推出的是想要的结果

  • 若出现代码错误,可以先思考以下三个问题:

    • 这道题目我举例推导状态转移公式了么?
    • 我打印dp数组的日志了么?
    • 打印出来了dp数组和我想的一样么?

2.斐波那契数

2.1题目

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 01 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1

给定 n ,请计算 F(n)

  • 示例一:
输入:n = 2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1
  • 示例二:
输入:n = 3
输出:2
解释:F(3) = F(2) + F(1) = 1 + 1 = 2
  • 示例三:
输入:n = 4
输出:3
解释:F(4) = F(3) + F(2) = 2 + 1 = 3

2.2解法:动态规划

2.2.1动态规划思路

动规五部曲:

(1)确定dp数组以及下标的含义

dp[i]的定义为:第i个数的斐波那契数值是dp[i]

(2)确定递推公式

题目已经把递推公式直接给我们了:状态转移方程 dp[i] = dp[i - 1] + dp[i - 2];

(3)dp数组初始化

题目中把如何初始化也直接给我们了,如下:

dp[0] = 0;
dp[1] = 1;
(4)确定遍历顺序

从递归公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,dp[i]是依赖 dp[i - 1] 和 dp[i - 2],那么遍历的顺序一定是从前到后遍历的

(5)举例推导dp数组

按照这个递推公式dp[i] = dp[i - 1] + dp[i - 2],我们来推导一下,当N为10的时候,dp数组应该是如下的数列:

0 1 1 2 3 5 8 13 21 34 55

如果代码写出来,发现结果不对,就把dp数组打印出来看看和我们推导的数列是不是一致的。

2.2.2代码实现

	public int fib(int n) {
        if(n<=1){
            return n;
        }
        //1、确定dp数组以及下标含义,下标n的元素代表了数字n的斐波那契数
        int[] dp=new int[n+1];
        //3、dp数组初始化
        dp[0]=0;
        dp[1]=1;
        //4、确定遍历顺序(注意:要到数字n)
        for(int i=2;i<=n;i++){
            //2、确定递归公式
            dp[i]=dp[i-1]+dp[i-2];
        }
        return dp[n];
    }

3.爬楼梯

3.1题目

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 12 个台阶。你有多少种不同的方法可以爬到楼顶呢?

  • 示例一:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
  • 示例二:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

3.2解法:动规

3.2.1动规思路

动规五部曲:

(1)确定dp数组以及下标的含义

dp[i]的定义为:第i层楼梯一共有dp[i]种方法

(2)确定递推公式

爬到第i层楼梯一共有两种情况:

  • 从第(i-1)层楼梯爬一个台阶
  • 从第(i-2)层楼梯爬二个台阶

故此,dp[i]=dp[i-1]+dp[i-2]

(3)dp数组初始化
dp[1] = 1;
dp[2] = 2;
(4)确定遍历顺序

从递归公式dp[i] = dp[i - 1] + dp[i - 2];中可以看出,dp[i]是依赖 dp[i - 1] 和 dp[i - 2],那么遍历的顺序一定是从前到后遍历的

(5)举例推导dp数组

image-20240501095829088

3.2.2代码实现

	public int climbStairs(int n) {
        if(n<=1){
            return n;
        }
        int[] dp=new int[n+1];
        dp[1]=1;
        dp[2]=2;
        for(int i=3;i<=n;i++){
            dp[i]=dp[i-1]+dp[i-2];
        }
        return dp[n];
    }

4.使用最小花费爬楼梯

4.1题目

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯

请你计算并返回达到楼梯顶部的最低花费。

  • 示例一:
输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。
- 支付 15 ,向上爬两个台阶,到达楼梯顶部。
总花费为 15 。
  • 示例二:
输入:cost = [1,100,1,1,1,100,1,1,100,1]
输出:6
解释:你将从下标为 0 的台阶开始。
- 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。
- 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。
- 支付 1 ,向上爬一个台阶,到达楼梯顶部。
总花费为 6 。

4.2解法:动规

4.2.1动规思路

(1)确定dp数组以及下标的含义

dp[i]的定义为:爬到第i层楼梯的最低花费

(2)确定递推公式

爬到第i层楼梯一共有两种情况:

  • 从第(i-1)层楼梯爬一个台阶,花费第[i-1]层楼梯的代价
  • 从第(i-2)层楼梯爬二个台阶,花费第[i-2]层楼梯的代价1

故此,dp[i]=Math.min(dp[i-1]+cost[i-1] , dp[i-2]+cost[i-2])

(3)dp数组初始化

新题目描述中明确说了 “你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。” 也就是说 到达 第 0 个台阶是不花费的,但从 第0 个台阶 往上跳的话,需要花费 cost[0]。

所以初始化 dp[0] = 0,dp[1] = 0;

dp[0] = 0;
dp[1] = 0;
(4)确定遍历顺序

因为是模拟台阶,而且dp[i]由dp[i-1]dp[i-2]推出,所以是从前到后遍历cost数组就可以了。

但是稍稍有点难度的动态规划,其遍历顺序并不容易确定下来。 例如:01背包,都知道两个for循环,一个for遍历物品嵌套一个for遍历背包容量,那么为什么不是一个for遍历背包容量嵌套一个for遍历物品呢? 以及在使用一维dp数组的时候遍历背包容量为什么要倒序呢?

(5)举例推导dp数组

image-20240501105504714

4.2.2代码实现

	public int minCostClimbingStairs(int[] cost) {
        int len=cost.length;
        int[] dp=new int[len+1];    //注意楼顶是数组最后一个元素的下一个
        dp[0]=0;
        dp[1]=0;
        for(int i=2;i<=len;i++){
            dp[i]=Math.min(dp[i-1]+cost[i-1] , dp[i-2]+cost[i-2]);
        }
        return dp[len];
    }

在这里插入图片描述

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

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

相关文章

SQL如何利用Bitmap思想优化array_contains()函数

目录 0 问题描述 1 位图思想 2 案例实战 3 小结 0 问题描述 在工作中&#xff0c;我们往往使用array_contains()函数来进行存在性问题分析&#xff0c;如判断某个数是否在某个数组中&#xff0c;但是当表数据量过多&#xff0c;存在大量array_contains()函数时&#xff0c;…

PHP定时任务框架taskPHP3.0学习记录7宝塔面板手动可以执行自动无法执行问题排查及解决方案(sh脚本、删除超过特定天数的日志文件、kill -9)

PHP定时任务框架taskPHP3.0学习记录 PHP定时任务框架taskPHP3.0学习记录1&#xff08;TaskPHP、执行任务类的实操代码实例&#xff09;PHP定时任务框架taskPHP3.0学习记录2&#xff08;环境要求、配置Redis、crontab执行时间语法、命令操作以及Screen全屏窗口管理器&#xff0…

无缝对接配电自动化:IEC104转OPC UA网关解决方案

随着水电厂自动化发展的要求&#xff0c;具有一定规模的梯级水电站越来越多&#xff0c;为了实现水电站的无人值班(少人值守)&#xff0c;并考虑到节能控制&#xff0c;电厂采用了集中监控。集中监控关注的是整个电网的安全稳定运行及电压、频率和整个电网的电力需求&#xff0…

中科院突破:TalkingGaussian技术实现3D人脸动态无失真,高效同步嘴唇运动!

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; 引言&#xff1a;探索高质量3D对话头像的新方法 在数字媒体和虚拟互动领域&#xff0c;高质量的3D对话头像技术正变得日益重要。这种技术能够在虚拟现实、电影…

好看流光风格个人主页源码下载

这是一款美观流光作风个人主页HTML源码&#xff0c;觉得挺喜欢的&#xff0c;需求的自行下载&#xff01; 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89105857 更多资源下载&#xff1a;关注我。

JAVA前端快速入门基础_javascript入门(02)

写在前面:本文用于快速学会简易的JS&#xff0c;仅做扫盲和参考作用 1.JavaScript函数 什么是函数:执行特定任务的代码块 1.1定义&#xff1a; 使用function来进行定义(类似于python里面的def 或者java和c里面的void&#xff0c;int这些返回类型开头)。定义规则如下: func…

开源、轻量、易用的服务器实时监控工具:哪吒探针

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 哪吒探针是一个开源、轻量、易用的服务器监控、运维工具&#xff0c;它有以下几个特点&#xff1a; 一键安装&#xff1a;可以一键安装面板与 Agent&#xff0c;并且支持 Linux、Windows、MacOS、OpenWRT…

【HMGD】使用CubeMx配置GD32F303系列单片机进行DMA ADC

原理图查看 查原理图可以看到GD32F103C8T6的官方开发板GD32303C-START-V1.0的PA1没有接任何东西 使用PA1作为ADC端口 CubeMX配置ADC和时钟 配置ADC通道 启用循环模式 配置此通道ADC分频 配置ADC DMA为循环模式 配置时钟 可根据手册配置最大HZ GD32F303最高频率设定 生成…

使用SDRPI运行openwifi和设置网口

目录 一 制作启动盘 二 使用串口的方式启动openwifi 三 无线连接 四 网口设置&#xff0c;有线连接 五 使用SSH登录 一 制作启动盘 在github上下载img文件&#xff0c;由于github上下载速度比较慢&#xff0c;我会上传网盘链接 githun下载img文件地址: https://git…

【Schrödinger薛定谔软件使用实战】- 4lyw蛋白实战

文章目录 软件选择1 pretein preparation1.1 import and process注意1.1.1 preprocess可能遇到的问题 1.2 review and modify1.3 refine1.3.1 optimize优化氢键网络1.3.2 minimize 氢原子会进行能量最小化 2 ligand prepare3 生成对接盒子-receptor grid generation3.1 recepto…

假设检验随想

⭐️ 前言 你会吵架吗&#xff1f;你会用数学吵架吗&#xff0c;不会的话就过来看看吧&#xff0c;哈哈 西方人发明了现代意义上的概率论&#xff0c;于是就想把它推广到生产和生活中。借助一大堆的概率论中的概念&#xff0c;他们发明了假设检验&#xff0c;想利用有限的数据…

Unity 实现新手引导遮罩

Unity 复写OnPopulateMesh 实现新手引导遮罩、包含点击事件触发区域判断 https://download.csdn.net/download/shenliang34/89247117

在线听歌播放器 梨花带雨网页音乐播放器 网页音乐在线听 源码

最新梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码下载 下 载 地 址 &#xff1a; runruncode.com/php/19749.html 梨花带雨播放器基于thinkphp6开发的XPlayerHTML5网页播放器前台控制面板,支持多音乐平台音乐解析。二开内容&#xff1a;修复播放器接口问题&am…

开启HIVE JDBC连接

开启HIVE JDBC连接 没有人能替你承受痛苦 也没有人能抢走你的坚强 目录 开启HIVE JDBC连接 1.开启命令 2.连接命令 3.hive连接jdbc报错 4.查看服务是否启动 》》》》》》开启HIVE JDBC连接《《《《《《 1.开启命令 hive --service hiveserver2 2.连接命令 beeline -u j…

动静态库(完结版)

文章目录 接上篇完成blog第三方库安装演示动态库加载原理一二三四 接上篇完成blog 上篇链接 第三方库安装演示 sudo yum install -y ncurses-devel下载完成之后 在系统目录下面一定能找到对应的头文件和库文件 此时使用第三方库: 编译之后按错误提示是对应的函数找不到,所以链…

Gitlab安装部署

Gitlab安装部署 一、下载对应的安装包 查看Linux系统的版本信息 cat /proc/version查看Linux系统发行版信息 cat /etc/redhat-release然后下载匹配版本的 gitlab&#xff0c;因为 gitlab 官网下载比较缓慢&#xff0c;所以这里附带了清华的镜像 Index of /gitlab-ce/yum/e…

Django后台项目开发实战一

开发环境使用 Anaconda, IDE 使用 pycharm 第一阶段 创建 Django 项目 在 Anaconda Prompt 中逐步输入下面的命令&#xff08;之后的所有命令都在这个&#xff09; 首先创建一个虚拟环境&#xff0c;名称自拟&#xff0c;python 版本我这里使用 3.9.18 关于 python 版本和…

【补充】图神经网络前传——图论

本文作为对图神经网络的补充。主要内容是看书。 仅包含Introduction to Graph Theory前五章以及其他相关书籍的相关内容&#xff08;如果后续在实践中发现前五章不够&#xff0c;会补上剩余内容&#xff09; 引入 什么是图&#xff1f; 如上图所示的路线图和电路图都可以使用…

Spring Security介绍(二) 主要组件(1) SecurityConfigurer

一、介绍 1、介绍 SecurityConfigurer 在 Spring Security 中是一个非常重要的角色。在前面的内容中曾经多次提到过&#xff0c;Spring Security 过滤器链中的每一个过滤器&#xff0c;都是通过 xxxConfigurer 来进行配置的&#xff0c;而这些 xxxConfigurer 实际上都是 Secu…

TCP通信 ,客户端服务端流程

TCP通信 TCP&#xff1a;传输层协议 特点&#xff1a;面向连接的安全的流式传输协议 面向链接 &#xff1a; 连接&#xff1a;三次握手&#xff0c;建立双向链接 断开&#xff1a;四次挥手&#xff0c;双向断开 安全的&#xff1a;通信过程会对通信进行校验&#xff0c;判…