动态规划之不同路径解决问题

简介: 动态规划之不同路径解决问题

1. 题目解析



题目链接选自力扣 : 不同路径

image.png

题目不难读懂, 就是遵循一个规则, 机器人从起点开始, 只允许向右或者向下行走, 不允许返回而最终到达终点时一共有多少种不同的路径. 比如在一个 2 * 3 的矩阵里, 从做烧焦起点(0,0) 到达终点右下角(1,2) 一共有多少种方法. 通过题目要求, 发现一共有三种不同路径的走法.

6961edbbf25be7cd7443508981e27986.png

2. 状态表示



这和我们前面几道动态规划不一样了. 它从一个一维的线性表变成了一个二维的. 但整体的思路还是不变的. 根据我们的题目要求, 定义 dp[i][j] 表示 从起始位置( 0, 0 ) 到终点 ( i , j ) 一共有多少种不同的路径方法数.


3. 状态转移方程



虽然现在的 dp 表变成了一个二维的 dp 表, 但是还是可以采取我们的最近一步划分问题.

何为最近一步呢 ? 看了前面的几篇文章相信你也和我一样不陌生了. 那这里我就直接划分了.

0a79fbd8ac35b9dcee79f8bdb58f9e99.png

当这个机器人想到达 ( i, j) 这个位置时就必须先到 ( i-1, j ) 的位置向下一步或者先到 ( i, j-1 ) 的位置后向前一步到达( i, j ) 位置. 那么此时 dp[i][j] 就分为了两种情况.


  1. 从( i-1, j ) 位置过来的.

必须经过 ( i-1, j ) 然后向下一步到达终点, 因此到达 ( i-1, j ) 有多少种方法, 那么最终经过 ( i-1, j ) 到达终点就有几种方法.


例如 : 到达 ( i-1, j ) 因为不能向上回退, 只有一条路. A-> B -> C. 最终通过 C 点到达终点, 只是在这个路径方法上多了一个点, 并非多了一条不同的路径. 即 A-> B -> C-> G. 因此最终到达 ( i-1, j ) 位置有多少种不同的路径方法到达终点就有几种.


此时正好对应我们的状态表示, 即 dp[i-1][j]


  1. 从( i, j-1 ) 位置过来的.


同样的, 必须先经过( i, j-1 ) 位置后向前一步到达终点. 因此到达 ( i, j-1 ) 这个点有多少种方法最终到达终点就有几种方法.


例如 : A-> B-> F 或者 A-> E-> F 一共条不同的路径. 最终到达终点时的路径只不过是多加了一个点并非多了一条新的路径. 最终为 A-> B-> F->G 以及 A-> E-> F-> G.


根据状态表示, 到达 ( i, j-1 ) 这个点有多少种路径则到达终点有多少种, 即 dp[i][j-1]


最终的dp[i][j] 为两种最近情况的总和. 即 dp[i][j] = dp[i][j-1] + dp[i-1][j]


4. 初始化



对于初始化, 目的就是为了防止我们填写 dp 表数据时发生越界. 比如在填写这个绿色五角星点时,. 根据我们的状态转移方程可以知道, 需要知道这个点的上一个位置和后一个位置的值. 但是很明显此时上一个位置时没有的越界了. 因此我们需要对它进行初始化防止后续填写 dp 表发生越界.


82b56f162cc29bf820925c7f0948fc00.png

对于这个题, 我们可以采取简单除暴的直接初始化的方法. 也就是把第一行和第一列都进行初始化了. 这样在使用到的时候就不会越界了. 那么这个值该初始化为多少好呢 ?

01a70edb1a9f227c21a70626f2597ca3.png细想这个路线. 对于第一行而言. 这上面的每一个点从起始点过来都只有一条路可以走. 即向右.

对于第一列而言. 这上面的每一个点从起始点过来也只有一条路可以走. 即向下. 因此初始化这一行和这一列时, 这上面的每一个点都应为 1.


但是这种方法还是比较麻烦的, 虽然它很直观. 为了将它放在填表的时候进行初始化, 根据上次讲解 解码方法 这个题时, 讲了一种多开一个格子的初始化方法. 这次依然用这种方法. 什么意思呢 ? 也就是让这个二维的 dp 数组多开一行多开一列.

6e933752595051960925f3f3d83b905e.png

红色的格子就是我们多开的一行和一列. 那么现在我们该如何进行初始化呢 ? 根据动态转移方程不难想. 当我们想初始化起始点的时候, 只需要知道它的上一个点和前一个点的路径数即可对吧 ?

0931e18fdd195f799b302ffb606045d3.png

上面说了, 原本这个矩阵的第一行和第一列上的每一个点都要为 1 才能保证我们填表的正确性. 在结合我们的动态转移方程. 也就是只需要保证起始点的前一个位置为 1 或者上一个位置为 1. 此时填表的时候就可以直接将起始点进行初始化了.


总的来说就需要保证起始点位置为 1. 通过状态方程在填表时就可以将原本矩阵的第一行和第一列进行初始化了.

d7aed5ae3850f49ccdc729dfb4d36c24.png

5. 填表顺序



这是一个二维的 dp 表. 从状态转移方程来说, 需要知道当前位置的前一个位置和上一个位置的路径总数. 因此填表的顺序毫无疑问是 从上往下填写每一行, 而每一行又从左往右填写


6. 返回值



此时我们的 dp 表多开了一行和一列 变成了 dp[m+1][n+1], dp 表中终点的位置存放的值对应从起点到终点的不同路径数. 对应到我们的 dp 表中则为 dp[m][n]. ( 注意下标关系 )


7. 代码演示



class Solution {
    public int uniquePaths(int m, int n) {
        // 1. 创建 dp 表
        // 注意多开了一行一列.
        int[][] dp = new int[m + 1][n + 1];
        // 2. 初始化
        // 确保起始点为 1. 保证起始点的上一个位置或者前一个位置为 1即可正确填写后续 dp 表
        dp[0][1] = 1; // 我选择原本矩阵起始点的上一个点.
        // dp[1][0] = 1; // 也可以选择原本矩阵起点的前一个点
        // 3. 填写 dp 表
        for(int i = 1; i <= m; i++) {
            for(int j = 1; j <= n; j++) {
                // 根据状态转移方程进行填表
                dp[i][j] = dp[i][j-1] + dp[i-1][j];
            }
        }
        // 4. 确认返回值
        return dp[m][n];
    }
}


相关文章
|
机器学习/深度学习 人工智能 算法
深度学习和强化学习有什么区别呢
【10月更文挑战第23天】深度学习和强化学习有什么区别呢
|
10月前
|
算法
MATLAB在风险管理中的应用:从VaR计算到压力测试
本文介绍如何使用MATLAB进行风险管理,涵盖风险度量(如VaR)、压力测试和风险分解。通过历史模拟法、参数法和蒙特卡洛模拟法计算VaR,评估投资组合在极端市场条件下的表现,并通过边际VaR和成分VaR识别风险来源。结合具体案例和代码实现,帮助读者掌握MATLAB在风险管理中的应用,确保投资组合的稳健性。
|
11月前
|
人工智能 Unix Java
[oeasy]python059变量命名有什么规则_惯用法_蛇形命名法_name_convention_snake
本文探讨了Python中变量命名的几种常见方式,包括汉语拼音变量名、蛇形命名法(snake_case)和驼峰命名法(CamelCase)。回顾上次内容,我们主要讨论了使用下划线替代空格以提高代码可读性。实际编程中,当变量名由多个单词组成时,合理的命名惯例变得尤为重要。
413 9
|
IDE 安全 数据管理
Visual Basic for Applications (VBA):自动化Office任务
【4月更文挑战第27天】**Visual Basic for Applications (VBA)** 是Microsoft Office中的宏语言,用于自动化Excel、Word、Outlook等应用的任务。VBA基于Visual Basic,通过编写代码控制应用行为,提升效率。文章介绍了VBA环境、基础语法,展示了在Excel(数据处理)、Word(文档管理)和Outlook(邮件自动化)中的应用。强调安全性和调试重要性,学习VBA能增强Office软件的功能,实现高效自动化工作流程。
615 0
|
机器学习/深度学习 计算机视觉 网络架构
【YOLOv8改进 - 注意力机制】HCF-Net 之 PPA:并行化注意力设计 | 小目标
YOLO目标检测专栏介绍了HCF-Net,一种用于红外小目标检测的深度学习模型,它通过PPA、DASI和MDCR模块提升性能。PPA利用多分支特征提取和注意力机制,DASI实现自适应特征融合,MDCR通过多层深度可分离卷积细化空间特征。HCF-Net在SIRST数据集上表现出色,超越其他方法。论文和代码分别在[arxiv.org](https://arxiv.org/pdf/2403.10778)和[github.com/zhengshuchen/HCFNet](https://github.com/zhengshuchen/HCFNet)上。YOLOv8的PPA类展示了整合注意力机制的结构
|
运维 监控 安全
构建高效运维体系的策略与实践
【10月更文挑战第7天】 本文旨在探讨如何构建高效的运维体系。从明确定义目标、优化流程、引入自动化工具、建立监控机制到提升团队能力,我们将全面解析高效运维体系的构建步骤和关键要素。通过具体策略和成功案例的分享,帮助运维团队提升工作效率、减少故障发生,并持续改进运维质量。
422 0
|
Web App开发 移动开发 JavaScript
面试官:说一下script 标签中 defer(推迟) 和 async(异步) 的区别
面试官:说一下script 标签中 defer(推迟) 和 async(异步) 的区别
435 0
|
移动开发 安全 API
阿里云最新域名注册及续费和转入收费价格表参考
目前域名注册管理机构(Verisign)已上调.com中英文域名成本,这一变动将直接影响到全球范围内.com域名价格,各大注册商的.com域名注册、续费、转移价格已同步上涨。以阿里云为例,此次涨价之后,.com英文域名的注册价格由原来的78元涨价到了83元,续费价格也涨到了90元,下面是2024年9月1日涨价之后,阿里云最新的域名注册及续费和转入最新收费价格表。
|
IDE 开发工具 Python
【Python】已解决:pip安装第三方模块(库)与PyCharm中不同步的问题(PyCharm添加本地python解释器)
【Python】已解决:pip安装第三方模块(库)与PyCharm中不同步的问题(PyCharm添加本地python解释器)
3162 0