Studying-代码随想录训练营day33| 动态规划理论基础、509.斐波那契函数、70.爬楼梯、746.使用最小花费爬楼梯

第33天,动态规划开始,新的算法💪(ง •_•)ง,编程语言:C++

目录

动态规划理论基础

动态规划的解题步骤

动态规划包含的问题

动态规划如何debug

509.斐波那契函数

70.爬楼梯 

746.使用最小花费爬楼梯

总结 


动态规划理论基础

文档讲解:代码随想录动态规划理论基础

动态规划(Dynamic Programming),简称DP,通常用以解决某一问题有很多子问题的情况。

动态规划中每一个状态一定是由上一个状态推导出来的,这一点区别于贪心,贪心没有状态推导,而是从局部直接选出最优。

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

在动态规划中dp[j]是由dp[j-weight[i]]推导出来的,然后取max(dp[j], dp[j - weight[i]] + value[i])。而贪心则是每次拿物品选一个最大的或者最小的就完事了,和上一个状态没有关系。所以贪心是解决不了动态规划的问题的。

动态规划的解题步骤

动态规划中,最重要的一个部分是状态转移公式,也即递推公式。但找到递推公式也只是一方面,我们在解题的时候,还需要构造dp数组,我们还需要确定dp数组中下标表示的含义,这样才能够有助于我们真正理解题目。

对于动态规划问题,我们可以把解题步骤拆解为如下五步:

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

解题过程中,依据上述5步进行。注意对dp数组的初始化,是在确定递推公式后的,因为有些初始化是要依据递推公式进行的。

动态规划包含的问题

动态规划一般包含的问题有:

  • 基础题目
  • 背包问题
  • 打家劫舍
  • 股票问题
  • 子序列问题

动态规划是一个很大的领域,对于后面的每一种问题,还需要进行单独的讲解。

动态规划如何debug

我们在解动态规划问题时,如果出现无法通过的时候,一定不要慌张,代码出现问题是很正常的。我们最重要的是不能让代码对我们而言是黑盒状态,就是我们都不确定它的运行顺序和结果。

最好的debug方式,就是把dp数组打印出来,看看结果究竟是不是按照自己思路推导的,又是哪一个部分出了错误。

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

在对动态规划问题进行debug时,我们一定要牢记三个问题:

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

牢记上述三个问题,基本就能够解决动态规划解题过程中遇到的问题。 


509.斐波那契函数

文档讲解:代码随想录斐波那契函数

视频讲解:手撕斐波那契函数

题目:

学习:本题是非常经典的数学题目之一,也是标准的动态规划题目。递推公式在题干中就已经给了我们,剩下的就是我们依照动规五部曲,逐步进行。

1.确定dp数组以及下标的含义:在这里我们可以定义一个vector型的dp数组,dp[i]定义为第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]的,因此遍历顺序一定要从前往后进行遍历。

5.举例推导dp数组:我可以依照我们上述构造的dp数组和递推关系,当n = 10时,dp数组应该为:0,1,1,2,3,5,8,13,21,34,55。如果发现结果不对,我们也可以通过打印dp数组来查看问题出在哪。

代码:

//时间复杂度O(n)
//空间复杂度O(n)
class Solution {
public:int fib(int n) {//动态规划,使用dp数组,存储斐波那契数列数值if(n < 2) return n; //0,1单独处理vector<int> dp(n + 1); //从0-N,dp(n)表示第n个数的斐波那契数值dp[0] = 0;dp[1] = 1;for(int i = 2; i <= n; i++){dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
};

代码:对于本题来说,实际上也可以不适用dp数组,我们只需要维护两个值就可以了

//时间复杂度O(n)
//空间复杂度O(1)
class Solution {
public:int fib(int n) {//动态规划,不使用dp数值,只找到第n个值if(n < 2) return n;int dp0 = 0;int dp1 = 1;int sum;for(int i = 2; i <= n; i++) {sum = dp0 + dp1;dp0 = dp1;dp1 = sum;}return dp1;}
};

代码:本题还可以使用递推公式进行,代码极度简便,但并不好想。

//时间复杂度O(2^n)
//空间复杂度O(n)
class Solution {
public:int fib(int n) {//递归法,非常恐怖if(n < 2) return n;else return fib(n - 1) + fib(n - 2);}
};

70.爬楼梯 

文档讲解:代码随想录爬楼梯

视频讲解:手撕爬楼梯

题目:

学习:本题实际上是斐波那契数的变种,递推公式都是一样的。这也可见动态规划问题能够想出递推公式确认是十分重要的。

对于本题来说,由于一次可以爬1或2个台阶,因此对于第3层台阶来说,可以从第一层爬2层台阶到达,也可以从第二层爬1层台阶到达。而到达第一层和第二层的种类分别是dp[1]和dp[2]因此,到达第三层的种类就为dp[1]+dp[2],之后的第四层也是如此,能够通过从第二层爬2阶到达,也能够通过从第三层爬1阶到达……

最后就能够得到同样的递推公式dp[n] = dp[n - 1] + dp[n - 2]。但要注意本题中与斐波那契数不同的式dp[0]在本题中是没有意义的,虽然我们给dp[0]赋值为1(因为dp[2]=2)也能够解决问题,但是dp[0]是没有实际意义的,因此本题更推荐给dp[1]和dp[2]进行初始化。

代码:

//时间复杂度O(n)
//空间复杂度O(n)
class Solution {
public:int climbStairs(int n) {//动态规划//1.确定dp数组以及下标的含义vector<int> dp(n + 1); //dp(n)表示爬n阶的方法//2.确定递归条件:dp(n) = dp(n - 1) + dp(n - 2);//3.dp数组初始化,因为dp(0)是没有意义的,且n也不会等于0,因此不需要初始化0if(n <= 1) return n;dp[1] = 1;dp[2] = 2;//4.确定遍历顺序for (int i = 3; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];//5.举例推导dp数组(打印dp数组)//cout << dp[i] << endl;}return dp[n];}
};

746.使用最小花费爬楼梯

文档讲解:代码随想录使用最小花费爬楼梯

视频讲解:手撕使用最小花费爬楼梯

题目:

学习:本题我们需要注意题干中的两个点:1.cost[i],是从i个台阶向上爬需要支付的费用,也就是我们只有向上爬了,才需要支付费用,我们站在i台阶上,是不需要支付cost[i]的。2.到达楼梯顶部不是指第最后的下标(cost.size() - 1)个台阶,实际上根据例子我们可以发现,是最后一个台阶还要再上一个台阶才是顶部的位置。

基于此,我们可以通过递归五部曲来求解本题。

1.确定dp数组以及下标的含义:我们可以构造一个vector型dp数组,其中dp[i]应该定义为到达第i个台阶所花费的最小体力,这样我们最后求出的dp[cost.size()]才是到达顶部的花费最小体力。

2.确定递推公式:对于第i个台阶来说,有两个途径能够得到dp[i],一个是dp[i - 1],一个是dp[i - 2]而我们需要得到最小的,因此dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])。

3.初始化dp数组:通过递推公式我们知道,至少需要两个数才能够推出后面的值,因此我们可以初始化dp[0] 和 dp[1](注意本题中题干给出了0下标的含义)

4.确定遍历顺序:显然本题也是从前往后进行遍历。

5.举例推导dp数组:

代码:

//时间复杂度O(n)
//空间复杂度O(n)
class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {//动态规划//1.确定dp数组及下标含义vector<int> dp(cost.size() + 1); //dp[n]表示上到第n个台阶所要消耗的最小花费//2.确定递推公式 dp[n] = min(dp[n - 1] + cost[n - 1], dp[n - 2] + cost[n - 2]);//3.dp数组初始化(规定cost.size() >= 2)dp[0] = 0; //爬的时候才消耗费用dp[1] = 0;//4.确定遍历顺序for(int i = 2; i <= cost.size(); i++) {dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);}return dp[cost.size()];}
};

总结 

动态规划开始,牢记动态五部曲,做题不慌张。

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

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

相关文章

音频demo:使用opencore-amr将PCM数据与AMR-NB数据进行相互编解码

1、README a. 编译 编译demo 由于提供的.a静态库是在x86_64的机器上编译的&#xff0c;所以仅支持该架构的主机上编译运行。 $ make编译opencore-amr 如果想要在其他架构的CPU上编译运行&#xff0c;可以使用以下命令&#xff08;脚本&#xff09;编译opencore-amr[下载地…

hdu物联网硬件实验3 按键和中断

学院 班级 学号 姓名 日期 成绩 实验题目 按键和中断 实验目的 实现闪灯功能转换 硬件原理 无 关键代码及注释 /* Button Turns on and off a light emitting diode(LED) connected to digital pin 13, when pressing a pushbutton attached…

[图解]SysML和EA建模住宅安全系统-13-时间图

1 00:00:00,480 --> 00:00:02,280 首先&#xff0c;我们来看&#xff0c;图画在哪里 2 00:00:02,290 --> 00:00:04,380 这个图 3 00:00:04,390 --> 00:00:06,180 你看&#xff0c;它是描述&#xff0c;刚才讲的 4 00:00:06,190 --> 00:00:09,010 描述这个活动 …

ISO 20000认证:驱动企业IT服务管理变革的利器

在信息技术驱动商业发展的今天&#xff0c;企业对高效、可靠和安全的IT服务需求日益增长。ISO 20000作为国际公认的IT服务管理标准&#xff0c;能够帮助企业在竞争激烈的市场环境中脱颖而出&#xff0c;实现IT服务管理的全面提升。本文将深入探讨ISO 20000认证如何帮助企业优化…

Linux忘记密码重置root密码、重置普通用户密码

重启看到选项按e reboot 或 init 62、移动到Linux开头的行在末尾添加 rw init/bin/bash3、按下Ctrlx引导启动 mount -o remount,rw /输入命令回车更改密码,输入新密码&#xff0c;别用小键盘&#xff0c;容易出错 passwd输入两次校验&#xff0c;出现updated successfully就…

进程,进程的调度,进程的调度算法(详解)ฅ( ̳• · • ̳ฅ)

目录 &#x1f607;进程的概念&#xff1a; &#x1f61a;进程的组成&#xff1a; &#x1f970;进程的调度&#xff1a; 一.进程调度的概念&#xff1a; 二.进程调度的方式&#xff1a; 三.进程调度的时机&#xff1a; &#x1f92a;进程的调度算法&#xff1a; 一.先…

Python 中什么是局部变量和全局变量

在Python编程中&#xff0c;理解变量的作用域是非常重要的。变量的作用域决定了变量在程序中的可见性和生命周期。Python中有两种主要的变量作用域&#xff1a;局部变量和全局变量。 1. 局部变量 1.1 定义 局部变量是定义在函数内部的变量&#xff0c;只能在函数内部访问。局…

纯前端低代码开发脚手架 - daelui/molecule

daelui/molecule低代码开发脚手架&#xff1a;分子组件开发、预览、打包 页面代码示例、大屏代码示例预览 可开发页面组件 可开发大屏组件 项目git地址&#xff1a;https://gitee.com/daelui/molecule 在线预览&#xff1a;http://www.daelui.com/daelui/molecule/app/index.…

分布式一致性算法:Raft学习

分布式一致性算法&#xff1a;Raft学习 1 什么是分布式系统&#xff1f; 分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。这些节点可能位于不同的物理位置&#xff0c;但它们协同工作以提供一个统一的计算平台或服务。分布式系统…

Leetcode 295.数据流的中位数

295.数据流的中位数 问题描述 中位数是有序整数列表中的中间值。如果列表的大小是偶数&#xff0c;则没有中间值&#xff0c;中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: Media…

【笔记】太久不用redis忘记怎么后台登陆了

&#xff01;首先启动虚拟机linux的centos7 2.启动finalshell 我的redis启动在根目录用 redis-server redis.conf --启动 systemctl status redis --查看redis状态 是否active redis-cli -h centos的ip地址 -p 你要用的redis端口号&#xff08;默认为6379&#xff09; -a 你…

UDP通讯实现

服务器端&#xff1a; 1.获取套接字 int fd;fdsocket(AF_INET,SOCK_DGRAM,0);if(fd<0){perror("socket");exit(0);} #include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol); -domain: 指定通信域&…

LInux安装

目录 1. LInux优点 1.1 安全性高 1.2 稳定性和可靠性高 1.3 开源和免费 1.4 资源利用效率 2. Linux虚拟机下载 2.1 VMware安装 2.2 虚拟机安装 2.3 Centos7下载 2.4 简单设置Centors-7 2.4.1 首次进入 2.4.2 联网设置 2.4.3 自动联网设置 2.4.4 自动锁屏设置 Li…

Hadoop-15-Hive 元数据管理与存储 Metadata 内嵌模式 本地模式 远程模式 集群规划配置 启动服务 3节点云服务器实测

章节内容 上一节我们完成了&#xff1a; Hive中数据导出&#xff1a;HDFSHQL操作上传内容至Hive、增删改查等操作 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机上搭建过一次&am…

C++初学者指南-5.标准库(第一部分)--顺序容器

C初学者指南-5.标准库(第一部分)–顺序容器 文章目录 C初学者指南-5.标准库(第一部分)--顺序容器标准顺序容器常见特点规律性&#xff1a;复制&#xff0c;分配&#xff0c;比较类型推导(C17)常用接口部分 array<T,size>vector\<T>C 的默认容器快速回顾迭代器范围插…

【粉丝福利 | 第8期】值得收藏!推荐10个好用的数据血缘工具

⛳️ 写在前面参与规则&#xff01;&#xff01;&#xff01; ✅参与方式&#xff1a;关注博主、点赞、收藏、评论&#xff0c;任意评论&#xff08;每人最多评论三次&#xff09; ⛳️本次送书1~4本【取决于阅读量&#xff0c;阅读量越多&#xff0c;送的越多】 目前市面上绝…

文档图像处理:大模型的突破与新探索

前言 随着数字化时代的到来&#xff0c;文档图像处理技术在各行各业扮演着越来越重要的角色。在2023第十二届中国智能产业高峰论坛&#xff08;CIIS 2023&#xff09;的专题论坛上&#xff0c;合合信息智能技术平台事业部副总经理、高级工程师丁凯博士分享了当前文档图像处理面…

如何学习和提升SQL

资料来源于腾讯技术直播&#xff0c;只作为学习记录&#xff0c;如有侵权&#xff0c;请联系作者进行删除

4.1 操作系统

大纲 进程管理重点&#xff0c;占本章历年考试一半分数&#xff0c; 前趋图、信号量和PV操作、死锁和银行家算法 出计算题 作业管理历年考试从来没有考过 操作系统概述 进程管理 进程的组成和状态 前趋图 进程资源图 真题 1

实验一 MATLAB \ Python数字图像处理初步

一、实验目的&#xff1a; 1&#xff0e;熟悉及掌握在MATLAB\Python中能够处理哪些格式图像。 2&#xff0e;熟练掌握在MATLAB\Python中如何读取图像。 3&#xff0e;掌握如何利用MATLAB\Python来获取图像的大小、颜色、高度、宽度等等相关信息。 4&#xff0e;掌握如何在M…