Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >解锁动态规划的奥秘:从零到精通的创新思维解析(4)

解锁动态规划的奥秘:从零到精通的创新思维解析(4)

作者头像
用户11295429
发布于 2025-01-03 01:54:08
发布于 2025-01-03 01:54:08
7600
代码可运行
举报
文章被收录于专栏:王的博客专栏王的博客专栏
运行总次数:0
代码可运行

解锁动态规划的奥秘:从零到精通的创新思维解析(4)

前言:

小编在前几天讲述了动态规划相关的题目,今天继续跟着上次的脚步,继续进行动态规划相关题目的讲解,下面我们一起走进动态规划的世界。

正文:

1.珠宝的最高价值

1.1.题目来源

和之前一样,本题同样来自于力扣,下面给出它的链接:LCR 166. 珠宝的最高价值 - 力扣(LeetCode)

1.2.题目解析

本题目其实就是个pro版本的不同的路径问题,这个问题小编在之前的博客解答过,由于本文章写的时候那篇文章还没有发布,所以各位想看那个题目的可以进我主页来看一下:忘梓.-CSDN博客,下面进入正题,本题目是给定我们一个二维矩阵的珠宝价,并且每一个位置都有其价值,现在给定了我们几个规则,简单来说就是:我们从左上角开始拿珠宝,每次我们可以选择从右边或者下边走进行拿珠宝直到我们走到珠宝架子的右下角,问我们如何拿珠宝才可以拿到最高价值的珠宝,经过我这么一说,相信不少小伙伴都可以想到不同的路径那个题目,只不过此时这个题目与那个题目的不同就是本题是求解走到右下角时的珠宝的最高价值,题目的分析就到这里,下面我们进行本题目的思路讲解。

1.3.思路讲解

对于动态规划的题目,我们还是需要设置好一个dp表(并不是每一个动态规划就只有一个dp表,之后小编也会讲解多状态dp表的题目),此时我们自然的可以设置一个二维的dp表(题目分析得来),然后我们就正常五步走来对动态规划的题目进行求解。

1.状态表示

此时对于状态表示,我们依旧是按照经验+题目分析的角度来正确的表示出dp表,一般我们可以以某个位置为开头,或者以某个位置为结尾来进行状态的分析,通过对题目的解读,此时我们可以将其状态表示为以[i,j]位置为结尾时,从开头到[i,j]时的珠宝的最大价值,之后我们根据这个状态就可以书写状态转移方程了。

2.状态转换方程

此时我们根据题目给予我们的帮助,可以知道此时我们可以往右拿珠宝或者往下拿珠宝,当我们计算dp[i] [j]的时候,可以先计算上面的价值或者左边的价值,取他们中的最大值,然后加上自身,就可以计算出dp[i] [j]的值,此时我们可以如下图进行分析:

此时我们通过max函数计算其中的最大值即可,此时我们让最大值再加上当前位置本身的值即可。其代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dp[i][j] = max(dp[i - 1][j],dp[i][j - 1]) + nums[i][j]
3.初始化

本题和之前讲的路径问题一样,我们在初始化的时候都可以加上几个虚拟节点,来减小我们为了初始化的次数,因为此时如果我们不用虚拟节点的话,我们就要对第一行和第一列进行初始化的操作,有了虚拟结点以后,就可以大大减少我们的工作量了,此时我们可以根据状态转换方程来推算此时我们如何初始化,此时虚拟节点应该遵循以下两个原则:

1.虚拟节点的值要保证后面填表是正确的。

2.下标的映射

此时我们可以推算出此时的第一行和第一列的值为0即可,这样就可以确保此时的虚拟节点的值不影响我们之后填表时的值(不明白的读者朋友可以自行画个表看一下,其实大多数虚拟节点我们都是可以很快的知道它们的值的)。

4.填表顺序

此时我们通过方程可以知晓此时的填表顺序是从上到下,从左到右的。

5.返回值

因为此时我们求得的是到达最后一个位置时的珠宝的最高价值,所以我们返回最后一个位置的值即可,即dp[m] [n]。

1.4.代码讲解

此时我们需要先知道题目给定我们的行和列,通过vector容器给定我们的接口就可以知晓,之后我们要开辟一个dp表,此时dp表要多开一行一列,里面的值均为0即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int m = frame.size(),n = frame[0].size();
vector<vector<int>>dp(m + 1,vector<int>(n + 1));

之后我们就根据状态转换方程进行填充dp表即可,此时我们不用填第一行和第一列的dp表了,因为这样会让我们越界,虚拟节点本来就是为了不越界诞生的,这样做的话之间的努力就白费了。在填完表后,返回最后一个位置的数据即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for(int i = 1 ; i <= m ;i++)
    {
        for(int j = 1 ; j <= n;j++)
        {
            dp[i][j] = max(dp[i - 1][j],dp[i][j-1]) + frame[i-1][j-1];
        }
    }
return dp[m][n];
1.5.完整代码展示
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int jewelleryValue(vector<vector<int>>& frame) {
        int m = frame.size(),n = frame[0].size();
        vector<vector<int>>dp(m + 1,vector<int>(n + 1));
        for(int i = 1 ; i <= m ;i++)
        {
            for(int j = 1 ; j <= n;j++)
            {
                dp[i][j] = max(dp[i - 1][j],dp[i][j-1]) + frame[i-1][j-1];
            }
        }
        return dp[m][n];
    }
};

2.下降路径的最小和

2.1.题目来源

和之前的题目一样,本题同样来自于力扣,下面小编给出该题目的链接:931. 下降路径最小和 - 力扣(LeetCode)

2.2.题目分析

本题目的分析也是比较容易的,此时我们通过读题目就可以知道本题的大致题意,这个题目简单来说,就是给定我们一个方形数组,此时我们需要从每一行选择一个数,选择下一个数的时候,当我们选择下一行的数据的时候,此时我们有三种选择方法,分别是:下左,正下方,下右方来进行选择,此时我们选择到最后一行的时候,其中把之前路径加起来的所有路径中的最小和,这就是本题目的题目分析,下面小编开始进行题目思路讲解。

2.3.思路讲解

对于动态规划的题目,我们应当还是需要先建立一个dp表,此时因为这个空间是二维的,所以我们需要构造一个二维的dp表,之后我们还是按照动态规划的分析的五步走就好。

1.状态表示

对于状态表示,无非就是经验 + 题目分析来进行作答(线性dp问题),此时我们可以以i位置为结尾或者开头进行状态表示,对于本题,小编的解法就是以i位置为结尾进行讨论,那么此时的dp[i] [i]应该表示为到达[i,j]时,此时的下降路径最小和,我们依据此时的状态表示,就可以书写出状态转换方程了。

2.状态转换方程

此时的方程我们可以根据题目的分析来进行求解,此时题目告诉我们往下走的方式有三种,所以对应着往上走的方法也是有三种的,分别是往上左来,正上方来,上右来,所以对应着的dp式子也有三种,因为要求最小下降路径和,所以我们应该求他们中的最小,然后加上当前位置的值即可,具体分析图可以看下图。

具体的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dp[i][j] = min(dp[i - 1][j - 1] ,dp[i - 1][j],dp[i - 1][j + 1]) + nums[i][j];
3.初始化

初始化同样也是一个令人头疼的问题,当然这个题目的初始化也是容易看出来的,如果我们想要直接初始化那么就需要对第一行,第一列以及最后一列进行初始化,可以说非常的麻烦,所以为了避免麻烦,我们还是需要虚拟节点来解决这个问题,对于虚拟节点,我们需要遵循以下两个原则:

1.虚拟节点的值要保证后面填表是正确的。

2.下标的映射。(原数组和dp表之间的差异,此时让原数组行列-1就是dp表对应的位置)

本题的虚拟节点填值难度不大,此时我们需要保证第一行全部为0,因为我们在真正的第一行时需要用到虚拟的第一行的值,为了不影响结果,此时我们让其它位置的结点为最大值,避免对于他们的使用,这就是本题的初始化,等会在代码的时候更好看出来。

4.填表顺序

因为我们是以i位置为结尾的,所以我们需要前面的数据,所以从上往下,从左往右填。

5.返回值

此时我们不知道最后一行哪个位置的值最小,所以此时我们仍需循环去找到最后一行最小的数,找到后返回即可。

2.4.代码讲解

首先,我们仍需设置一个dp表,此时这个dp表要多开辟两列,多开辟一行,并且将里面的值先全部设置为int的最大值,之后我们再给特殊的第一行进行二次初始化。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int m = matrix.size(),n = matrix[0].size(); //前面表示行,后面表示列
vector<vector<int>> dp(m + 1,vector<int>(n + 2,INT_MAX));
for(int i = 0; i < n + 2 ; i++)
dp[0][i] = 0;  //让第一行为0

之后我们还是老老实实的按照状态转换方程填表即可,此时填表我们可以直接从第二行开始填,到最后一行结束,从第二列开始填,到倒数第二列结束,此时我们就完成了dp表的填写。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for(int i = 1 ; i <= m;i++)
    {
        for(int j = 1 ; j<= n ;j++)
        {
            dp[i][j] = min(dp[i-1][j - 1] , min(dp[i-1][j],dp[i-1][j + 1])) + matrix[i - 1][j - 1]; //min函数只可以比骄两个数,对于三个数可以嵌套处理
        }
    }

在所有数据填完后,我们仅需找到最后一行数据的最小值即可,摘到后返回即可(循环+最小值函数)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int ret = INT_MAX;
for(int i = 1 ; i <= n ;i++)
ret = min(ret,dp[m][i]);
return ret;
2.5.完整代码展示
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) {
        int m = matrix.size(),n = matrix[0].size(); //前面表示行,后面表示列
        vector<vector<int>> dp(m + 1,vector<int>(n + 2,INT_MAX));
        for(int i = 0; i < n + 2 ; i++)
        dp[0][i] = 0;  //让第一行为0
        for(int i = 1 ; i <= m;i++)
        {
            for(int j = 1 ; j<= n ;j++)
            {
                dp[i][j] = min(dp[i-1][j - 1] , min(dp[i-1][j],dp[i-1][j + 1])) + matrix[i - 1][j - 1]; //min函数只可以比骄两个数,对于三个数可以嵌套处理
            }
        }
        int ret = INT_MAX;
        for(int i = 1 ; i <= n ;i++)
        ret = min(ret,dp[m][i]);
        return ret;
    }
};

3.总结

截止到目前,本文的内容已经全部结束了,今天小编还是讲述了两个题目,希望各位读者好好的理解,如果有不懂的地方可以随时私信小编,小编会在空闲时间及时回复,最近我在实训,所以文章发布的有点慢,各位读者朋友见谅,不过当你看到这篇文章的时候,可能小编已经结束实训了,因为这是我的库存(理直气壮),一起学习的时光总是短暂的,那么各位大佬们,我们下一篇文章见啦!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
解锁动态规划的奥秘:从零到精通的创新思维解析(5)
小编在前几日分享了关于动态规划的题目,今天我们继续沿着之前的思路,深入探索动态规划的魅力。今天要讲解的依旧是路径问题,与前面讲过的题目在解法上有一定相似之处。如果大家对这类题目的解法还不太熟悉,可以回顾一下之前的文章,巩固基础。话不多说,让我们进入今天的代码之旅!
用户11295429
2025/01/10
730
解锁动态规划的奥秘:从零到精通的创新思维解析(5)
解锁动态规划的奥秘:从零到精通的创新思维解析(3)
小编在前几日书写了关于动态规划习题的博客(PS:其实这些都是我的存稿,我已经好久没写博客了截止到现在,确实摆烂),今天各位继续跟着小编的步伐,走进动态规划的世界,接下来我们将会·讲述一个比较新的动态规划问题:路径问题。
用户11295429
2025/01/03
500
解锁动态规划的奥秘:从零到精通的创新思维解析(3)
解锁动态规划的奥秘:从零到精通的创新思维解析(9)
小编在前几日写了关于动态规划中的多状态dp的问题,此时小编将会讲述一个动态规划我们常常会遇到的一类问题——股票问题,股票问题就类似小编上一篇所讲述的粉刷房子的问题,可以通过一个二维的dp表来代替多个一维的dp表。买卖股票算是一个很经典的问题了,下面小编简单介绍一下买卖股票问题。
用户11295429
2025/04/18
390
解锁动态规划的奥秘:从零到精通的创新思维解析(9)
解锁动态规划的奥秘:从零到精通的创新思维解析(8)
小编在前几日讲述了关于动态规划的习题,下面小编继续跟着上次的步伐,继续进入多状态dp问题的讲解(但是今天这个题目不需要多状态),今天由于小编的精力有限,所以我就仅仅先讲述一个题目,等小编过几天精力恢复过来就给各位正常的每日两题的讲解。
用户11295429
2025/04/16
970
解锁动态规划的奥秘:从零到精通的创新思维解析(8)
解锁动态规划的奥秘:从零到精通的创新思维解析(6)
在动态规划的众多问题中,多状态DP问题是一个非常重要的类别。它的难点在于如何设计合适的状态表示和转移方程,从而高效地解决问题。
用户11295429
2025/01/19
880
解锁动态规划的奥秘:从零到精通的创新思维解析(6)
解锁动态规划的奥秘:从零到精通的创新思维解析(10)
前几天,我写了一篇关于动态规划的文章,今天继续为大家带来一些动态规划相关的习题解析。本次分享的两道题依然围绕“股票”问题展开,不过相比之前的题目,难度有所提升。希望能为大家的学习提供帮助!
用户11295429
2025/05/02
750
解锁动态规划的奥秘:从零到精通的创新思维解析(10)
解锁动态规划的奥秘:从零到精通的创新思维解析(2)
小编在前几日讲述了关于动态规划的题目,今天小编继续进行动态规划相关题目的书写,动态规划的题目相较于小编之前讲述的习题难度是蛮大的,希望各位可以克服困难,最终掌握动态规划的题,下面就进入本文的讲题环节。
用户11295429
2025/01/03
740
解锁动态规划的奥秘:从零到精通的创新思维解析(2)
解锁动态规划的奥秘:从零到精通的创新思维解析(7)
在前几天的文章中,小编为大家讲解了动态规划中多状态 DP 问题的相关内容。今天,我们将延续上篇文章的主题,继续深入剖析多状态 DP 的解题思路和技巧。快系好安全带,准备好,我们的算法世界之旅再次启程!
用户11295429
2025/02/04
720
解锁动态规划的奥秘:从零到精通的创新思维解析(7)
【动态规划篇】- 路径问题
因为到达[1][1]这个位置共有一种路径,所以我们仅需将dp[1][0]或者dp[0][1]位置初始化为1,其余位置初始化为0即可。
_孙同学
2025/03/30
880
【动态规划篇】- 路径问题
解锁动态规划的奥秘:从零到精通的创新思维解析(1)
在算法的世界里,动态规划(Dynamic Programming, DP)以其强大的问题分解与优化能力,占据着极为重要的地位。无论是在学术研究还是实际应用中,它都广泛用于解决最优子结构和重叠子问题的复杂场景。从路径规划到资源分配,从游戏策略到数据压缩,动态规划的方法论为我们提供了一把破解复杂问题的利器。然而,初学者往往会被它的理论抽象和实现细节所困扰。本文将通过一道经典动态规划习题的详细讲解,帮助大家深入理解其本质,并掌握在实际问题中如何灵活运用。希望通过这篇文章,您能对动态规划的“自顶向下”与“自底向上”有更清晰的认识,从而在算法学习的旅程中迈出扎实的一步。下面我先从几个方面介绍动态规划。
用户11295429
2024/12/20
1470
解锁动态规划的奥秘:从零到精通的创新思维解析(1)
动态规划 —— 路径问题-下降路径最小和
https://leetcode.cn/problems/minimum-falling-path-sum/description/
迷迭所归处
2024/11/19
1020
动态规划 —— 路径问题-下降路径最小和
【算法专题】动态规划之路径问题
题目:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径?
YoungMLet
2024/03/01
2150
【算法专题】动态规划之路径问题
【动态规划2】路径问题
动态规划在解决路径问题时非常常见,特别是在图论和网络优化问题中。一般来说,动态规划用于解决那些具有重叠子问题和最优子结构性质的问题。路径问题通常涉及找到从起点到终点的最佳路径,可以是最短路径、最长路径或者满足特定条件的路径等。
南桥
2024/07/26
1480
【动态规划2】路径问题
算法训练之动态规划(二)
这个题目需要讨论的是由左上角到右下角的路径总数~我们可以按照动态规划的步骤来进行一步步分析~
用户11352420
2025/04/11
240
算法训练之动态规划(二)
【动态规划】状态 dp
状态表示:以 dp[i][j] 为结尾,走到 dp[i][j] 位置时一共有几种方式
2的n次方
2024/10/15
960
【动态规划】状态 dp
【算法/训练】:动态规划DP
动态规划(Dynamic Programming,DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学等领域中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题
IsLand1314
2024/10/15
4370
【算法/训练】:动态规划DP
动态规划 —— 路径问题-礼物的最大价值
https://www.nowcoder.com/practice/2237b401eb9347d282310fc1c3adb134?tpId=265&tqId=39288&ru=/exam/oj
迷迭所归处
2024/11/19
1040
动态规划 —— 路径问题-礼物的最大价值
动态规划 —— 路径问题-不同路径 ||
https://leetcode.cn/problems/unique-paths-ii/description/
迷迭所归处
2024/11/19
2240
动态规划 —— 路径问题-不同路径 ||
DP:解决路径问题
二维动态规划(DP)模型是一种通过引入两个维度的状态和转移方程来解决复杂问题的技术。它在许多优化和组合问题中广泛应用,尤其是那些需要考虑二维数组或矩阵的情况。
用户11305458
2024/10/09
2020
DP:解决路径问题
动态规划 —— dp 问题-买卖股票的最佳时机III
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/description/
迷迭所归处
2024/11/19
1060
动态规划 —— dp 问题-买卖股票的最佳时机III
推荐阅读
相关推荐
解锁动态规划的奥秘:从零到精通的创新思维解析(5)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验