代码随想录 | Day35 | 动态规划 :最小花费爬楼梯不同路径不同路径II

代码随想录 | Day35 | 动态规划 :最小花费爬楼梯&&不同路径&&不同路径II

动态规划应该如何学习?-CSDN博客

动态规划学习:

1.思考回溯法(深度优先遍历)怎么写

注意要画树形结构图

2.转成记忆化搜索

看哪些地方是重复计算的,怎么用记忆化搜索给顶替掉这些重复计算

3.把记忆化搜索翻译成动态规划

基本就是1:1转换

文章目录

  • 代码随想录 | Day35 | 动态规划 :最小花费爬楼梯&&不同路径&&不同路径II
    • 746.使用最小花费爬楼梯
    • 62.不同路径
      • 思路:
      • 1.回溯 DFS
      • 2.记忆化搜索
      • 3.动态规划
    • 63.不同路径II
      • 1.回溯DFS
      • 2.记忆化搜索
      • 3.动态规划

746.使用最小花费爬楼梯

746. 使用最小花费爬楼梯 - 力扣(LeetCode)

详解在这篇博客,这里不再赘述。

动态规划应该如何学习?-CSDN博客

62.不同路径

62. 不同路径 - 力扣(LeetCode)

思路:

和爬楼梯差不多,爬楼梯是从i-1和i-2往上走,这个是从左边和上边才能走到当前位置

到当前点(m,n)的路径数量为到(m-1,n)的数量加上(m,n-1)的路径数量

到(3,3)的路径数量就是到(2,3)路径和(3,2)路径数量的和然后就会一直递归到(1,2),(2,1)直接返回一条路径

1.回溯 DFS

还是自底向上进行回溯,由当前块(i,j)的上边(i-1,j)和左边(i,j-1)

1.返回值和参数

dfs含义就是到传入的(m,n)位置的所有路径的数量,所以返回int

int dfs(int m,int n)

2.终止条件

if(n<1||m<1)return 0;
if(m==1&&n==1)return 1;
if(m==1&&n==2)return 1;
if(m==2&&n==1)return 1;

到小于1的地方路径数量为0

开始位置(1,1)到(1,1),(1,2),(2,1)都是只有一条路径,直接返回1

3.本层逻辑

到当前点(m,n)的路径数量为到(m-1,n)的数量加上(m,n-1)的路径数量

return dfs(m-1,n)+dfs(m,n-1);

完整代码:

class Solution {
public:int dfs(int m,int n){   if(n<1||m<1)return 0;if(m==1&&n==1)return 1;if(m==1&&n==2)return 1;if(m==2&&n==1)return 1;return dfs(m-1,n)+dfs(m,n-1);}int uniquePaths(int m, int n) {return dfs(m,n);}
};
//lambda
class Solution {
public:int uniquePaths(int m, int n) {function<int(int,int)> dfs=[&](int m,int n)->int{if(n<1||m<1)return 0;if(m==1&&n==1)return 1;if(m==1&&n==2)return 1;if(m==2&&n==1)return 1;return dfs(m-1,n)+dfs(m,n-1);};return dfs(m,n);}
};

2.记忆化搜索

加入dp数组作为备忘录,初始化dp为-1

每次返回都给dp赋值之后再返回。碰到不是-1的说明被计算过了,直接用

class Solution {
public:int dfs(int m,int n,vector<vector<int>>& dp){   if(n<1||m<1)return 0;if(m==1&&n==1)return dp[m][n]=1;if(m==1&&n==2)return dp[m][n]=1;if(m==2&&n==1)return dp[m][n]=1;if(dp[m][n]!=-1)return dp[m][n];return dp[m][n]=dfs(m-1,n,dp)+dfs(m,n-1,dp);}int uniquePaths(int m, int n) {vector<vector<int>> dp(m+1,vector<int>(n+1,-1));return dfs(m,n,dp);}
};
//lambda
class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m+1,vector<int>(n+1,-1));function<int(int,int)> dfs=[&](int m,int n)->int{if(n<1||m<1)return 0;if(m==1&&n==1)return dp[m][n]=1;if(m==1&&n==2)return dp[m][n]=1;if(m==2&&n==1)return dp[m][n]=1;if(dp[m][n]!=-1)return dp[m][n];return dp[m][n]=dfs(m-1,n)+dfs(m,n-1);};return dfs(m,n);}
};

3.动态规划

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

含义就是到达(i,j)的路径数量,即dp[i][j]是到达(i,j)的路径数量

2.确定递推公式

就是到达左边和上边的数量之和

dp[i][j]=dp[i][j-1]+dp[i-1][j];

3.dp数组如何初始化

第一行和第一列都是只有1

vector<vector<int>> dp(m+1,vector<int>(n+1,0));
for(int i=1;i<=n;i++)dp[1][i]=1;
for(int i=1;i<=m;i++)dp[i][1]=1;    

4.确定遍历顺序

dp[i][j]=dp[i][j-1]+dp[i-1][j]

要依赖前面的计算结果,所以是从前往后遍历

for(int i=2;i<=m;i++)for(int j=2;j<=n;j++)dp[i][j]=dp[i][j-1]+dp[i-1][j];

完整代码

class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m+1,vector<int>(n+1,0));for(int i=1;i<=n;i++)dp[1][i]=1;for(int i=1;i<=m;i++)dp[i][1]=1;    for(int i=2;i<=m;i++)for(int j=2;j<=n;j++)dp[i][j]=dp[i][j-1]+dp[i-1][j];return dp[m][n];}
};

63.不同路径II

63. 不同路径 II - 力扣(LeetCode)

思路都一样就说一下怎么处理这个障碍

1.回溯DFS

终止条件多加一个,如果判断当前i,j是1的话那就直接返回0,说明只要经过这条路路径会加0

class Solution {
public:int dfs(vector<vector<int>> &obstacleGrid,int i,int j){if(i<0||j<0)   return 0;if(obstacleGrid[i][j]==1)return 0;if(i==0&&j==0)return 1;if(i==1&&j==0)return 1;if(i==0&&j==1)return 1;return dfs(obstacleGrid,i-1,j)+dfs(obstacleGrid,i,j-1);}int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {if(obstacleGrid[0][0]==1)return 0;return dfs(obstacleGrid,obstacleGrid.size()-1,obstacleGrid[0].size()-1);}
};

2.记忆化搜索

就是遇到障碍的时候要先把dp[i][j]赋值为0,这样后面加这块的路径数量只会加0

class Solution {
public:int dfs(vector<vector<int>> &obstacleGrid,int i,int j,vector<vector<int>> &dp){if(i<0||j<0)   return 0;if(obstacleGrid[i][j]==1)return dp[i][j]=0;if(i==0&&j==0)return dp[i][j]=1;if(i==1&&j==0)return dp[i][j]=1;if(i==0&&j==1)return dp[i][j]=1;if(dp[i][j]!=-1)return dp[i][j];return dp[i][j]=dfs(obstacleGrid,i-1,j,dp)+dfs(obstacleGrid,i,j-1,dp);}int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {if(obstacleGrid[0][0]==1)return 0;vector<vector<int>> dp(obstacleGrid.size(),vector<int>(obstacleGrid[0].size(),-1));return dfs(obstacleGrid,obstacleGrid.size()-1,obstacleGrid[0].size()-1,dp);}
};
//lambda
class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {if(obstacleGrid[0][0]==1)return 0;vector<vector<int>> dp(obstacleGrid.size(),vector<int>(obstacleGrid[0].size(),-1));function<int(int,int)> dfs=[&](int i,int j)->int{if(i<0||j<0)   return 0;if(obstacleGrid[i][j]==1)return dp[i][j]=0;if(i==0&&j==0)return dp[i][j]=1;if(i==1&&j==0)return dp[i][j]=1;if(i==0&&j==1)return dp[i][j]=1;if(dp[i][j]!=-1)return dp[i][j];return dp[i][j]=dfs(i-1,j)+dfs(i,j-1);};return dfs(obstacleGrid.size()-1,obstacleGrid[0].size()-1);}
};

3.动态规划

1.初始化的时候要判断,第一行和第一列如果遇到障碍,只有障碍前面的是1,后面的都是0

2.由于我们初始化dp全为0,在后面如果遇到障碍直接continue跳过本次循环即可

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int m=obstacleGrid.size();int n=obstacleGrid[0].size();if(obstacleGrid[0][0]==1||obstacleGrid[m-1][n-1]==1)return 0;vector<vector<int>> dp(m,vector<int>(n,0));for(int i=0;i<n&&obstacleGrid[0][i]!=1;i++)dp[0][i]=1;for(int i=0;i<m&&obstacleGrid[i][0]!=1;i++)dp[i][0]=1;for(int i=1;i<m;i++)for(int j=1;j<n;j++)if(obstacleGrid[i][j]==1)continue;elsedp[i][j]=dp[i-1][j]+dp[i][j-1];return dp[m-1][n-1];}
};

注:路径是从1开始,路径II是从0开始,小细节注意一下就行

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

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

相关文章

【大模型系列】Mini-InternVL(2024.10)

Paper&#xff1a;https://arxiv.org/pdf/2410.16261Github&#xff1a;https://github.com/OpenGVLab/InternVL/tree/main/internvl_chat/shell/mini_internvlAuthor&#xff1a;Zhangwei Gao et al. 上海人工智能实验室 文章目录 0 总结(省流版)1 模型结构1.1 InternViT-300M…

使用Virtual Audio Cable捕获系统音频输出并使用Python处理

一、下载安装Virtual Audio Cable&#xff0c;软件下载地址和安装过程略过。 二、Virtual Audio Cable使用方法Virtual Audio Cable使用笔记一&#xff1a;使用Virtual Audio Cable将播放器的音频流传输到真实声卡驱动中_virtual audio cable control panel-CSDN博客 三、打开…

MySQL 数据库备份与恢复全攻略

MySQL 数据库备份与恢复全攻略 引言 在现代应用中&#xff0c;数据库是核心组件之一。无论是个人项目还是企业级应用&#xff0c;数据的安全性和完整性都至关重要。为了防止数据丢失、损坏或意外删除&#xff0c;定期备份数据库是必不可少的。本文将详细介绍 MySQL 数据库的备…

C++17 折叠表达式

折叠表达式 C17之前处理参数包 C17折叠表达式的出现让我们不必再用递归实例化模板的方式来处理参数包。 在 C17之前&#xff0c;实现必须分成两个部分&#xff1a; 终止条件递归条件 这样的实现不仅写起来麻烦&#xff0c;对 C编译器来说也很难处理。C17折叠表达式能显著的…

大语言模型数据流程源码解读(基于llama3模型)

文章目录 前言一、数据进入LlamaForCausalLM(LlamaPreTrainedModel)类二、数据进入LlamaModel(LlamaPreTrainedModel)类1、input_ids的embedding编码2、position_ids位置获取3、causal_mask因果mask构建1、causal_mask调用2、因果mask代码解读(_update_causal_mask)4、hidden_s…

Docker镜像的创建、修改与导出

Docker镜像的创建、修改与导出 前言一、创建Docker镜像1. 基于已有镜像创建方法一:修改现有镜像方法二:使用Dockerfile通过源码编译安装nginx二、修改Docker镜像1. 基于已有镜像创建新镜像方法一:修改现有镜像2. 使用`docker commit`命令创建新镜像方法一:提交正在运行的容…

Depcheck——专门用于检测 JavaScript 和 Node.js 项目中未使用依赖项的工具

文章目录 Depcheck 是什麽核心功能&#x1f4da;检测未使用的依赖&#x1f41b;检测缺失的依赖✨支持多种文件类型&#x1f30d;可扩展性 安装与使用1. 安装 Depcheck2. 使用 Depcheck Depcheck 的应用总结项目源码&#xff1a; Depcheck 是什麽 来看一个常见错误场景&#x1…

Sqoop的安装配置及使用

Sqoop安装前需要检查之前是否安装了Tez,否则会产生版本或依赖冲突&#xff0c;我们需要移除tez-site.xml&#xff0c;并将hadoop中的mapred-site.xml配置文件中的mapreduce驱动改回成yarn&#xff0c;然后分发到其他节点&#xff0c;hive里面配置的tez也要移除&#xff0c;然后…

sqoop抽取数据报驱动包不存在的问题

sqoop抽取数据报驱动包不存在的问题 报错示例:需要把相应的jar包放到sqoop的lib目录下: 可以正常查询

SpringBoot后端开发常用工具详细介绍——flyway数据库版本控制工具

文章目录 什么是flyway简介为什么要使用flyway 流程介绍整合springboot添加pom文件配置flyway向resource/db/migration添加sql文件 注意事项1. 迁移报错2. 迁移顺序 参考 什么是flyway 简介 为什么要使用flyway 我们在开发时往往会有这样一种情况&#xff1a; 进行软件开发…

HCIP-HarmonyOS Application Developer V1.0 笔记(一)

HarmonyOS的系统特性 硬件互助&#xff0c;资源共享;一次开发&#xff0c;多端部署;统一OS&#xff0c;弹性部署。 分布式软总线&#xff1a;分布式任务调度、分布式数据管理、分布式硬件虚拟化的基座 18N的独立设备 1个手机&#xff0c;8种设备&#xff08;车机&#xff0c…

深入解析HTTP与HTTPS的区别及实现原理

文章目录 引言HTTP协议基础HTTP响应 HTTPS协议SSL/TLS协议 总结参考资料 引言 HTTP&#xff08;HyperText Transfer Protocol&#xff09;超文本传输协议是用于从Web服务器传输超文本到本地浏览器的主要协议。随着网络安全意识的提高&#xff0c;HTTPS&#xff08;HTTP Secure…

stm32使用SIM900A模块实现MQTT对接远程服务器

SIM900A模块是一种GSM/GPRS无线通信模块,它可以通过SIM卡连接移动通信网络,并通过串口或USB接口与微控制器或计算机进行通信。 SIM900A驱动代码如下: #include "stm32f10x.h" #include "stdio.h" #include "stdlib.h" #include "sim900a…

算法:LeetCode283_移动零_Java实现

package com.leetcode;import java.util.Arrays;/*** LeetCode283&#xff1a;移动零*/ public class LeetCode283 {public static void moveZeroes(int[] nums) {//1.remove nums中0int slowIndex0;for(int fastindex0;fastindex<nums.length;fastindex){if(nums[fastindex…

Docker搭建基于Nextcloud的个人云盘/私有云盘/个人相册/家庭NAS

安装配置Docker 官方安装文档&#xff1a;https://docs.docker.com/engine/install/ Docker常用命令&#xff1a;https://blog.csdn.net/qq_43003203/article/details/139532097?spm1001.2014.3001.5502 Docker镜像仓库配置方法和国内常用镜像仓库地址&#xff1a; 输入&a…

杂项笔记

这个好像如果如果分配空间就会执行 这个扩容好像会进行拷贝 4 没懂 X x 0; X x1 {0,0}; 都会调用X::X(int x1, int x2 0)

【VUE点击父组件按钮,跳转到子组件】

要实现在Vue中&#xff0c;父组件通过点击按钮进入子组件的 <el-dialog> 弹窗&#xff0c;并在弹窗中嵌套 <el-table> 表格&#xff0c;可以按照以下步骤进行编写代码&#xff1a; 在父组件中&#xff0c;定义一个数据属性用于控制子组件弹窗的显示与隐藏。 data…

HTTP介绍及请求过程

HTTP(HyperText Transfer Protocol),即超文本传输协议,是一种用于分布式、协作式和超媒体信息系统的应用层协议。以下是关于 HTTP 的详细介绍: 一、基本概念 定义与作用: HTTP 是互联网上应用最为广泛的一种网络协议,它定义了客户端和服务器之间请求和响应的标准方式。…

Python从入门到高手7.3节-列表的常用操作方法

目录 7.3.1 列表常用操作方法 7.3.2 列表的添加 7.3.3 列表的查找 7.3.4 列表的修改 7.3.5 列表的删除 7.3.6 与列表有关的其它操作方法 7.3.7 与10月说再见 7.3.1 列表常用操作方法 列表类型是一种抽象数据类型&#xff0c;抽象数据类型定义了数据类型的操作方法。在本…

2024.10.29- Linux(CentOS7)笔记(1)

一、Linux文件系统的介绍 Linux的文件系统与Unix的文件系统类似&#xff0c;也是一个树形结构。 最基本的是根目录&#xff1a;/ 。相当于windows文件系统的盘符。 /&#xff1a; 根路径&#xff0c; 根路径下有以下文件夹 ​ /bin -> usr/bin : 存储的是用户级别的指令…