【二】【动态规划NEW】91. 解码方法,62. 不同路径,63. 不同路径 II

91. 解码方法

一条包含字母 A-Z 的消息通过以下映射进行了 编码 :

‘A’ -> “1”
‘B’ -> “2”

‘Z’ -> “26”
要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,“11106” 可以映射为:

“AAJF” ,将消息分组为 (1 1 10 6)
“KJF” ,将消息分组为 (11 10 6)
注意,消息不能分组为 (1 11 06) ,因为 “06” 不能映射为 “F” ,这是由于 “6” 和 “06” 在映射中并不等价。

给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数 。

题目数据保证答案肯定是一个 32 位 的整数。

示例 1:

输入:s = “12”
输出:2
解释:它可以解码为 “AB”(1 2)或者 “L”(12)。
示例 2:

输入:s = “226”
输出:3
解释:它可以解码为 “BZ” (2 26), “VF” (22 6), 或者 “BBF” (2 2 6) 。
示例 3:

输入:s = “06”
输出:0
解释:“06” 无法映射到 “F” ,因为存在前导零(“6” 和 “06” 并不等价)。

提示:

1 <= s.length <= 100
s 只包含数字,并且可能包含前导零。

利用递归思想写动态规划,字符串s返回解码的方法数,f(i)表示0~i区间的解码方法数.
字符串s的长度是n,我们需要得到f(n).
f(i)函数求解0~i区间的解码方法数,
可以让i位置字符单独解码,也可以让i和i-1位置字符两个一起解码.

如果让i位置字符单独解码,此时产生的解码方法数是f(i-1).
如果让i和i-1位置共同解码,此时产生的解码方法数是f(i-2).

如果让i位置字符单独解码需要满足的条件是s[i]!=‘0’.
如果让i和i-1位置字符共同解码需要满足的条件是s[i-1]!=‘0’,并且i-1和i位置字符属于1~26.

根据递归思想直接写动态规划写法.
状态表示,定义dp[i]表示0~i区间的解码方法数.
状态转移方程,如果让i位置字符单独解码,此时产生的解码方法数是dp[i-1].
如果让i和i-1位置共同解码,此时产生的解码方法数是dp[i-2].
填表顺序,填写i位置状态需要用到i-1,i-2位置状态,i需要从小到大.
初始化,特判,最开始的可以直接得出答案的就手动填写,越界的用三目表达式解决.

#define debug // 定义 debug 宏
#ifdef debug // 如果定义了 debug
#define bug(code) do{cout<<"L"<<__LINE__<<":"<<endl;code;}while(0) // 定义 bug 宏,输出当前行号并执行代码块
#else
#define bug(code) do{}while(0) // 如果没有定义 debug,bug 宏为空操作
#endifclass Solution {
public:int ret; // 用于存储结果的整数string s; // 输入字符串vector<int>dp; // 动态规划数组void solve(){ // 解决问题的函数ret=0; // 初始化结果为 0dp.assign(s.size(),-1); // 将动态规划数组初始化为 -1,大小为输入字符串的长度dp[0]=1; // 初始条件,dp[0] 设为 1for(int i=1;i<dp.size();i++){ // 从第 1 个字符开始遍历字符串int ans=0; // 用于存储当前字符的解码方法数if(s[i]!='0') ans+=dp[i-1]; // 如果当前字符不是 '0',则可以单独解码,加上 dp[i-1]if(s[i-1]!='0'&&(s[i-1]-'0')*10+(s[i]-'0')<=26) ans+=(i-2>=0?dp[i-2]:1); // 如果前一个字符不是 '0',且当前和前一个字符组成的数字小于等于 26,则可以合并解码,加上 dp[i-2](如果 i-2 小于 0,则加 1)dp[i]=ans; // 更新 dp[i] 为当前的解码方法数}ret=dp[dp.size()-1]; // 最后的结果是 dp 数组的最后一个值bug( // 如果定义了 debug,输出 dp 数组for(int i=0;i<dp.size();i++){ // 遍历 dp 数组cout<<dp[i]<<" "; // 输出 dp 数组的每一个值}cout<<endl; // 换行);}int numDecodings(string _s) { // 主函数,接收输入字符串ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); // 加速输入输出s=_s; // 将输入字符串赋值给成员变量 sif(s[0]=='0') return 0; // 如果字符串以 '0' 开头,返回 0solve(); // 调用 solve 函数求解return ret; // 返回结果}
};

62. 不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

示例 1:
在这里插入图片描述

输入:m = 3, n = 7
输出:28
示例 2:

输入:m = 3, n = 2
输出:3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。

  1. 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右
  3. 向下 -> 向右 -> 向下
    示例 3:

输入:m = 7, n = 3
输出:28
示例 4:

输入:m = 3, n = 3
输出:6

提示:

1 <= m, n <= 100
题目数据保证答案小于等于 2 * 109

f(i,j)表示从(0,0)位置到达(i,j)位置的路径数,我们需要的返回值是f(row,col).
f(i,j)=f(i-1,j)+f(i,j-1).
递归出口,如果是(0,0)位置,返回1.
如果越界了返回0.

利用递归思想直接写动态规划,定义状态标识dp[i][j]表示(0,0)位置到达(i,j)位置的路径数,需要的返回值是dp[row][col].
状态转移方程,dp[i][j]=dp[i-1][j]+dp[i][j-1].
初始化,特判,越界情况用三目表达式解决.
填表顺序,i需要从小到大填写.

#define debug // 定义 debug 宏
#ifdef debug // 如果定义了 debug
#define bug(code) do{cout<<"L"<<__LINE__<<":"<<endl;code;}while(0) // 定义 bug 宏,输出当前行号并执行代码块
#else
#define bug(code) do{}while(0) // 如果没有定义 debug,bug 宏为空操作
#endif  
class Solution {
public:int row, col; // 定义行数和列数int ret; // 用于存储结果的整数vector<vector<int>> dp; // 动态规划数组void solve() { // 解决问题的函数ret = 0; // 初始化结果为 0dp.assign(row + 1, vector<int>(col + 1, -1)); // 初始化 dp 数组为 -1,大小为 (row+1) x (col+1)for (int i = 1; i <= row; i++) { // 遍历每一行for (int j = 1; j <= col; j++) { // 遍历每一列if (i == 1 && j == 1) { // 如果是起点位置 (1, 1)dp[i][j] = 1; // 起点位置的路径数为 1continue; // 跳过后续计算}dp[i][j] = (i - 1 >= 1 ? dp[i - 1][j] : 0) + (j - 1 >= 1 ? dp[i][j - 1] : 0); // 计算当前位置的路径数}}ret = dp[row][col]; // 最后的结果是 dp 数组的右下角值bug( // 如果定义了 debug,输出 dp 数组for (int i = 1; i <= row; i++) { // 遍历 dp 数组的每一行for (int j = 1; j <= col; j++) { // 遍历 dp 数组的每一列cout << dp[i][j] << " "; // 输出 dp 数组的每一个值}cout << endl; // 换行}cout << endl; // 换行);}int uniquePaths(int _m, int _n) { // 主函数,接收输入的行数和列数ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 加速输入输出col = _n, row = _m; // 将输入的行数和列数赋值给成员变量solve(); // 调用 solve 函数求解return ret; // 返回结果}
};

63. 不同路径 II

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 1 和 0 来表示。

示例 1:
在这里插入图片描述

输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:

  1. 向右 -> 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右 -> 向右
    示例 2:
    在这里插入图片描述

输入:obstacleGrid = [[0,1],[0,0]]
输出:1

提示:

m == obstacleGrid.length
n == obstacleGrid[i].length
1 <= m, n <= 100
obstacleGrid[i][j] 为 0 或 1

网格里面有障碍物,填表的时候,障碍物的位置是不需要填写的,并且为了不影响其他位置的填写,如果是障碍物dp值设置为0即可,如果不设置为0,在状态转移方程哪里就需要多判断一下.
用三目运算符解决越界的情况.

#define debug // 定义 debug 宏
#ifdef debug // 如果定义了 debug
#define bug(code) do{cout<<"L"<<__LINE__<<":"<<endl;code;}while(0) // 定义 bug 宏,输出当前行号并执行代码块
#else
#define bug(code) do{}while(0) // 如果没有定义 debug,bug 宏为空操作
#endif
class Solution {
public:vector<vector<int>> arr; // 存储输入的障碍物网格int ret; // 用于存储结果的整数vector<vector<int>> dp; // 动态规划数组void solve() { // 解决问题的函数dp.assign(arr.size(), vector<int>(arr[0].size(), -1)); // 初始化 dp 数组为 -1,大小与输入网格相同for (int i = 0; i < arr.size(); i++) { // 遍历每一行for (int j = 0; j < arr[0].size(); j++) { // 遍历每一列if (arr[i][j] == 1) dp[i][j] = 0; // 如果当前位置是障碍物,路径数为 0if (arr[i][j] == 1) continue; // 如果当前位置是障碍物,跳过后续计算if (i == 0 && j == 0) { dp[i][j] = 1; continue; } // 起点位置的路径数为 1dp[i][j] = (i - 1 >= 0 ? dp[i - 1][j] : 0) + (j - 1 >= 0 ? dp[i][j - 1] : 0); // 计算当前位置的路径数}}ret = dp[arr.size() - 1][arr[0].size() - 1]; // 最后的结果是 dp 数组的右下角值}int uniquePathsWithObstacles(vector<vector<int>>& _obstacleGrid) { // 主函数,接收输入的障碍物网格ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 加速输入输出arr = _obstacleGrid; // 将输入的障碍物网格赋值给成员变量solve(); // 调用 solve 函数求解return ret; // 返回结果}
};

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

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

相关文章

基于Matlab的车牌识别停车场出入库计时计费管理系统(含GUI界面)【W6】

简介&#xff1a; 在当今城市化进程加快的环境下&#xff0c;停车管理成为了一个日益重要和复杂的问题。城市中的停车资源有限&#xff0c;如何高效利用和管理这些资源&#xff0c;不仅关乎市民出行便利性&#xff0c;也涉及到城市交通拥堵、环境污染等诸多问题的解决。 传统的…

Denoising Prior Driven Deep Neural Network for Image Restoration

之所以能够检索到这篇论文是想看看该论文是如何利用多尺度相似性解决图像去噪问题&#xff0c;除了摘要和结论&#xff0c;论文中两次提到这个术语。next section是指section 4。然后整个section 4&#xff0c;根本没有提多尺度的事儿&#xff0c;更别说解决了。又看了一下The …

【idea】解决springboot项目中遇到的问题

一、Maven报错Could not find artifact com.mysql:mysql-connector-j:pom:unknown in aliyunmaven解决及分析 报错 创建springboot项目&#xff0c;勾选数据库驱动&#xff0c;springboot版本为3&#xff0c;现在改成了2.7.2&#xff0c;Maven就发生了报错Could not find art…

CCAA质量管理【学习笔记】​​ 备考知识点笔记(三)质量管理方法与常见工具

第二部分 质量管理领域专业知识 《质量管理体系基础考试大纲》中规定的考试内容&#xff1a; 3.2 质量管理领域专业知识 a) 了解质量管理方法与工具相关知识&#xff0c;包括&#xff1a; 质量管理方法与工具的内涵与作用、发展历程与应用现状、分类与选择常用的应用软件…

Vue使用vue-esign实现在线签名 加入水印

Vue在线签名 一、目的二、样式三、代码1、依赖2、代码2.1 在线签名组件2.1.1 基础的2.1.2 携带时间水印的 2.2父组件 一、目的 又来了一个问题&#xff0c;直接让我在线签名&#xff08;还不能存储base64&#xff09;&#xff0c;并且还得上传&#xff0c;我直接***违禁词。 好…

每日5题Day25 - LeetCode 121 - 125

每一步向前都是向自己的梦想更近一步&#xff0c;坚持不懈&#xff0c;勇往直前&#xff01; 第一题&#xff1a;121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int maxProfit(int[] prices) {if(prices.length 1){return 0;}//dp…

TJA1145休眠唤醒调试

目录 项目场景:TJA1145引脚图问题描述SPI链路验证休眠唤醒休眠唤醒配置唤醒报文配置代码相关寄存器:模式寄存器使能CAN唤醒设置唤醒边沿检测事件状态及捕获寄存器CANFD报文不会被识别为有效的唤醒帧项目场景: 最近开发过程中,选择了这颗芯片,踩了很多坑,总算是把这个芯片…

mysql报错Access denied for user ‘root‘,navicat可以连接mysql,spring不能连mysql

首先修改配置文件跳过验证&#xff0c;编辑你自己挂载的配置文件的位置 #查找my.cnf位置 sudo find / -name "my.cnf"编辑mysql配置文件 vim /opt/soft/mysql/conf/my.cnf #在[mysqld]下面添加 skip_grant_tables#重启mysql docker restart mysql#进入容器 docke…

在 Windows 环境下安装mysql步骤(MySQL)

文章目录 一、下载 MySQL二、解压安装包到磁盘三、配置环境&#xff08;管理员权限&#xff09;四、安装 MySQL&#xff08;管理员权限&#xff09; 一、下载 MySQL 如下图&#xff1a;为你的电脑下载对应操作系统的 MySQL 安装包 二、解压安装包到磁盘 三、配置环境&#x…

抽象工厂模式(大话设计模式)C/C++版本

抽象工厂模式 C 参考&#xff1a;https://www.cnblogs.com/Galesaur-wcy/p/15927110.html #include <iostream> using namespace std;// 抽象产品Department ,定义具体产品的公共接口 class Department { public:virtual ~Department() default;virtual void Insert()…

CC2500和CC1101移植说明

主要通过如何移植、移植注意、关于芯片配置、如何生成导出配置四大步骤来说明CC2500和CC1101移植 首先通过下图1这个宏进行选择 如何移植 要移植的部分在 CC2500_hal.c 和 CC2500_hal.h中, 搜索 "//移植" 就可以定位到 库 所需的依赖, 需要根据 您的环境实现这些…

(done) 什么是 perplexity 困惑度?

参考&#xff1a;https://www.youtube.com/watch?vB_2bntDYano 困惑度 perplexity 是一种用来衡量语言模型性能的度量&#xff0c;类似于交叉熵。 困惑度越低越好&#xff0c;越低说明一个模型越好。 一个典型的公式在下面&#xff1a;

Python学习打卡:day06

day6 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day648、函数综合案例49、数据容器入门50、列表的定义语法51、列表的下标索引1、列表的下标&#xff08;索引&#xff09;2、列表的下标&#xff08…

CCAA质量管理【学习笔记】​​ 备考知识点笔记(四)

第四节 质量非数据资料分析的基础工具 1 关 联 图 2.1 概念 所谓关联图&#xff0c;就是对关系复杂而相互纠缠的问题&#xff0c;依据原因—结果或目的一手段等关系&#xff0c; 在逻辑上用箭头把各要素之间的因果关系连接起来&#xff0c;厘清复杂问题、整理语言文字资料…

技术转管理,是灾难还是奇迹?

深耕技术or转战管理&#xff1f;this is a question! 如果你还没有想好&#xff0c;那请继续往下看&#xff01; 技术专家&#xff1a;技术前瞻者、方案构建者、难题破解者、团队聚核者 管理专家&#xff1a;战略规划者、高效组织者、变革引领者、团队建设者 特点和重心都不在…

iPad键鼠充电otg转接器 | LDR6020解决方案

随着科技的快速发展&#xff0c;iPad已经成为我们日常生活中不可或缺的一部分。它不仅是一个娱乐工具&#xff0c;更是一个高效的生产力工具。为了更好地满足用户的需求&#xff0c;iPad支持在充电的同时连接鼠标和键盘&#xff0c;极大地提升了使用的便捷性和效率。 iPad键鼠同…

干部选拔任用的六条原则

在干部选拔任用的过程中&#xff0c;为确保选拔出的干部能够真正符合党和人民的期望&#xff0c;必须遵循以下六条原则&#xff1a; 一、党管干部原则 党管干部原则是指在整个干部选拔任用过程中&#xff0c;党要发挥总揽全局、协调各方的领导作用&#xff0c;确保选拔出的干…

省去烦恼!轻松实现一台电脑登录多个微信号的秘诀揭秘!

你知道如何在同一台电脑上登录多个微信号&#xff0c;并实现聚合聊天吗&#xff1f; 今天&#xff0c;我将分享一个多微管理神器——个微管理系统&#xff0c;帮助你解决这一问题&#xff01; 1、多号同时登录&#xff0c;聚合聊天 无论你有多少个微信号&#xff0c;都可以一…

2024年【安全生产监管人员】试题及解析及安全生产监管人员考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全生产监管人员试题及解析是安全生产模拟考试一点通总题库中生成的一套安全生产监管人员考试试题&#xff0c;安全生产模拟考试一点通上安全生产监管人员作业手机同步练习。2024年【安全生产监管人员】试题及解析及…

智慧停车场定位导航系统的实现与优化

随着城市车辆数量的激增&#xff0c;大型停车场的运营挑战日益严峻。维小帮停车场导航定位系统通过集成先进的室内定位技术和大数据分析&#xff0c;为停车场提供了一套高效、便捷的导航定位服务方案&#xff0c;有效解决了停车难、找车难、管理难等问题。 一、系统核心功能的…