动态规划Dynamic Programming

在这里插入图片描述

 上篇文章我们简单入门了动态规划(一般都是简单的上楼梯,分析数据等问题)点我跳转,今天给大家带来的是路径问题,相对于上一篇在一维中摸爬滚打,这次就要上升到二维解决问题,但都用的是动态规划思想嘛,所以大差不差,且听我慢慢道来。
还是用一样的方法,用同样的分析思路和技巧来分析问题解决问题。
路径规划
不同路径
在这里插入图片描述

  • 状态表示
     这道题我们需要知道的是从左上角位置走到右下角位置总共有多少的路径,我们可以将问题拆分,题目中所说,机器人每次只能向下或者向右移动一步,所以我们到达右下角位置是怎么到达的呢?
    如图
    在这里插入图片描述所以到达目标的方法就是到达这两个位置方法的总和。
    在这里插入图片描述
    因此这道题的状态表示就是到达ij位置总共的方法数。
  • 状态转移方程
    有了上边的分析,我们可以很清晰地知道
    状态转移方程为

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

  • 初始化
     初始化顺序即填表顺序是从左上角到右下角,但是我们应该怎么初始化呢?如果套用我们的状态转移方程,我们会发现在数租的边缘部分一定会遇到越界的情况。
    在这里插入图片描述
     所以在初始化时,我们可以将数组多开一行一列,这样就可以解决越界访问的问题,如何初始化这个表格呢?我们来试着分析。
    在这里插入图片描述
    其他位置全部初始化为0,这样就可以避免多开的数组影响我们后续的得到的结果。
  • 填表顺序
    填表顺序就是从左上角向左下角进行填写。
  • 返回值
    很简单,就是返回填表后到达i,j位置时的值即可
    接下来我们就可以根据分析出的结论写代码了。

class Solution {
public:int uniquePaths(int m, int n) {//new出一个二维数组,并将他们的值初始化为0vector<vector<int>> dp(m+1,vector<int>(n+1));//这里应该怎么给空间啊dp[0][1]=1;for(int i=1;i<=m;i++)//先填每一行for(int j=1;j<=n;j++)//再填每一列  dp[i][j]=dp[i-1][j]+dp[i][j-1];return dp[m][n];}
};

在这里插入图片描述
这里还有一道十分相仿的题目,多了一步扩展的思维而已,尝试一下吧!
不同路径2


第二道题
珠宝的最高价值

在这里插入图片描述
 如果说上一道题对标的是上一篇中的上楼梯的方法数,那么这道题对标的就是上楼梯最小花费。
思路和上一道题目很像,一起来看一看。

  • 状态表示
     同样要创建一个二维数组,到达ij位置可以拿到的珠宝价值最高,那么状态表示就是到达ij位置能拿到的最大珠宝价值,说白了就是所以路径中求和最大的一条路径。
  • 状态转移方程
     移动方式和上一道题目一样,但是相比于上一道题目的相加,这道题目就是从上边或者左边到达ij位置时,他们两个谁的路径和最大。因为上一道题目已经解释很清楚了,这里就不再画图赘述。

dp[i][j]=max(dp[i-1][j],dp[i][j-1];

  • 填表顺序
     从左上角向右下角。要注意是从下表为1,1位置开始填表的。
  • 初始化
     初始化方式和前边那道题目大同小异,只不过我们多开的数组默认为0不用管就行,因为第一个位置只需要加上他这个位置的财宝价值即可。
  • 返回值
    返回到达左下角位置能达到的最高价值数。
    我们还是直接来展示代码吧,毕竟和前边那道题很像,除了状态转移方程不同。
    代码如下
class Solution {
public:int jewelleryValue(vector<vector<int>>& frame) {int m=frame.size();int 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][j-1],dp[i-1][j])+frame[i-1][j-1];return dp[m][n];}
};

在这里插入图片描述
第三道题
下降路径最小和
在这里插入图片描述
 首先来进行题目解析,这道题目只需要从上到下找到最小的路径即可,而且在某位置可以向下边三个位置进行跳转。

  • 状态表示
     状态表示就是到达ij位置时,需要的最小路径和,然后找出最后一行中最小的,就找到了最小路径下降和。
  • 状态转移方程
    可以来画图分析一下
    在这里插入图片描述
     根据我们的状态表示,我们需要找到最小路径和,只需要找到这个位置上边三种情况的最小路径和即可。
    在这里插入图片描述
    当然,到达ij位置时,还需要加上ij位置上的值。
    故而状态转移方程为

dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j+1],dp[i-1][j]))+matrix[i-1][j-1];//要注意这里位置的对应

这里状态对应的问题后边会解释到。

  • 初始化
    这里初始化是一个问题,问题在于在我们求第一行时,第一行的上边并没有数据,访问dp[-1][-1]势必会造成越界访问,如何解决呢?有了上边题目的铺垫,只需要扩展数组即可。
    相信大家已经看到了上边的画图中分别用两种颜色标记,如何初始化才能不影响后续的结果呢?
    在这里插入图片描述
     因为这道题目的数组开的并不规则,所以对应位置容易混淆,如果你匆匆写代码的话,势必会出现这样的问题,
    在这里插入图片描述
    还会出现这样的问题
    在这里插入图片描述
     第一种就是没有空控制好dp表的填写,导致初始化时的INT_MAX参与了运算,第二种就是因为多开两列,多开一行导致的位置判断不准确,以至于越界访问了。

  • 填表顺序
    很明显,从上往下进行填表

  • 返回值
     这里返回值和之前不太一样,需要找到最后一行元素中最小的一个,然后返回即可。
     代码如下,一定要尝试自己写一下,这道题是正方形表格,但是我作为长方形表格来做了,大家可以忽略这些小细节哈。

class Solution {
public:int minFallingPathSum(vector<vector<int>>& matrix) {int m=matrix.size();int n=matrix[0].size();vector<vector<int>> dp(m+1,vector<int> (n+2,INT_MAX));//怎么把两边初始化为int_max;//cout<<int_max;for(int k=0;k<=n+1;k++){dp[0][k]=0;}for(int i=1;i<=m;i++){for(int j=1;j<=n+1;j++)//这里要注意,只需要初始化我们需要的部分{dp[i][j]=min(dp[i-1][j-1],min(dp[i-1][j+1],dp[i-1][j]))+matrix[i-1][j-1];//要注意这里位置的对应}}//此时只需找到最后一行的最小值。int ret=INT_MAX;for(int j=1;j<=n;j++){ret=min(ret,dp[m][j]);}return ret;}
};

 本文到此结束,感谢大家观看,有问题及时提出,我会积极解决的。

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

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

相关文章

手机termux上用hydra在线暴力穷举破解

HYDRA 是一个在线暴力破解工具&#xff0c;速度快&#xff0c;穷举稳定&#xff0c;支持50线程的暴力穷举破解&#xff0c;兼容的协议也多&#xff0c;telnet, ftp, http, https, smb, 多数网页服务的databases&#xff0c;应用广泛。 在手机termux上也可以轻松实现。 不废话…

开源博客项目Blog .NET Core源码学习(10:App.Framwork项目结构分析)

开源博客项目Blog的解决方案总共包括4个项目&#xff0c;其中App.Hosting项目包括所有的页面及控制器类&#xff0c;其它项目主要提供数据库访问、基础类型定义等。这四个项目的依赖关系如下图所示&#xff0c;本文主要分析App.Framwork项目的主要结构及主要文件的用途。   …

水瓶座性格分析及星座配对!

水瓶座性格分析及星座配对&#xff01; 标签&#xff1a;水瓶座 水&#xff0f;瓶&#xff0f;座 1.20~2.18 “珍爱生命&#xff0c;远离水瓶” 这是一个被水瓶座折磨的巨蟹文艺男青年的呐喊 “都是外星人&#xff0c;根本没法沟通” 这是号称水瓶最佳基友的逆生长射手妹子…

21.同步模式-保护性暂停

1.Guarded Suspension,用在一个线程等待另一个线程的执行结果。 2.一个结果从一个线程传递到另一个线程&#xff0c;让他们关联同一个GuardedObject 保护对象。 3.如果有结果不断从一个线程到另一个线程&#xff0c;那么可以使用消息队列。 4.join方法和Future的实现&#x…

JavaScript原型、原型对象、原型链系列详解(三)

(三)、JavaScript原型链 原型链 在 JavaScript 中&#xff0c;对象之间的继承是通过原型链来实现的。每个对象都有一个指向原型对象的内部链接&#xff0c;也就是 [[Prototype]] 属性。这个链接的作用是如果对象本身没有某个属性或方法&#xff0c;就会去它的原型对象上找&…

Linux 进程通信:匿名管道、实现进程池

目录 一、进程间通信 1、 为什么需要进程通信 2、发展和分类 二、管道 1、概念 2、特点 2、复制并共享 3、用fork来共享管道原理 4、站在文件描述符角度-深度理解管道 5、站在内核角度-管道本质 三、匿名管道 1、概念 2、创建 3、snprintf 4、父子进程中进行单…

小程序英文口语发音评测

一、英文口语评测需求 在全球化的今天&#xff0c;英语已经成为了世界上最重要的国际语言之一。无论是在国际商务、科技研究、教育还是日常生活中&#xff0c;英语都扮演着举足轻重的角色。因此&#xff0c;掌握英文口语的能力对于个人的职业发展、学术研究以及跨文化交流都具…

【Linux】vim配置及安装方法

注 安装方法在文章最后 配置文件的位置 在目录 /etc/ 下面&#xff0c;有个名为vimrc的文件&#xff0c;这是系统中公共的vim配置文件&#xff0c;对所有用户都有效。而在每个用户的主目录下&#xff0c;都可以自己建立私有的配置文件&#xff0c;命名为“.vimrc”。例如&…

atoi函数详解

atoi函数使用方法 在c官网中是这样介绍atoi函数的 通俗的讲就是把字符串中的字符数字转换为整形数字&#xff0c;遇到空格就跳过&#xff0c;如果在字符串开始遇到不是有效的整数比如说abc就直接返回0&#xff0c;如果遇到像这种情况123abc345这个就只返回123&#xff0c;这个…

C语言数据结构之计数排序

世中逢尔 雨中逢花 目录 计数排序的介绍 代码展示 时间复杂度和空间父复杂度 计数排序的用途 计数排序的局限性 计数排序的介绍 排序原理 计数排序又称为鸽巢原理&#xff0c;是对哈希直接定址法的变形应用。 是一个不比较排序算法&#xff0c;通过计数将时间复杂度降到了O…

大型网站集群管理负载均衡

课程介绍 结合企业大规模应用&#xff0c;解决应用高并发问题&#xff0c;解决单节点故障问题&#xff0c;缓存数据库的应用。学完掌握知识点&#xff1a;企业应用实现四七层负载均衡&#xff0c;以及Nginx等应用的高可用性&#xff0c;Redis缓存数据库的部署应用以及高可用方…

【Redis】优惠券秒杀

全局唯一ID 全局唯一ID生成策略&#xff1a; UUIDRedis自增snowflake算法数据库自增 Redis自增ID策略&#xff1a;每天一个key&#xff0c;方便统计订单量ID构造是 时间戳 计数器 Component public class RedisIdWorker {// 2024的第一时刻private static final long BEGIN…

Unity 背包系统中拖拽物体到指定位置或互换位置效果的实现

在Unity中&#xff0c;背包系统是一种常见的游戏系统&#xff0c;可以用于管理和展示玩家所持有的物品、道具或装备。 其中的拖拽功能非常有意思&#xff0c;具体功能就是玩家可以通过拖拽物品图标来移动物品在背包中的位置&#xff0c;或者将物品拖拽到其他位置或界面中&…

29双体系Java学习之编程的基本过程和类的通用格式

编程的基本过程 类的通用格式 ★小贴士 类的设计应遵循单一职责原则&#xff08;SRP&#xff09;&#xff0c;即只能让一个类有且仅有一个职责&#xff0c;以保证修改的可能性尽量少。

DEll R440 LC下的硬件日志收集步骤(注意:此方法收集的日志里无操作系统的日志);

一&#xff0c; LC下的硬件日志收集步骤&#xff08;注意&#xff1a;此方法收集的日志里无操作系统的日志&#xff09;&#xff1b; 开机看到屏幕左上角出现F10的提示的时候&#xff0c;敲击F10&#xff0c;进入LC的界面&#xff1a; 找到U盘的类似文件&#xff0c;就是最终生…

无人驾驶中的坐标转换

无人驾驶中的坐标转换 无人车上拥有各种各样的传感器&#xff0c;每个传感器的安装位置和角度又不尽相同。对于传感器的提供商&#xff0c;开始并不知道传感器会以什么角度&#xff0c;安装在什么位置&#xff0c;因此只能根据传感器自身建立坐标系。无人驾驶系统是一个多传感器…

Windows/Linux-openEuler系统使用路由侠内网穿透,部署项目详细教程

文章目录 Windows/Linux-openEuler系统使用路由侠内网穿透&#xff0c;部署项目详细教程一、在windows系统下载安装路由侠并实现项目部署1、下载路由侠并注册安装到Windows系统2、点击内网映射&#xff0c;添加映射&#xff0c;注册域名前缀3、选择网站应用4、配置你想要代理项…

ubuntu上一款好用的串口工具screen

看名字&#xff0c;你猜他是什么&#xff1f; 安装 sudo apt install screen 然后将USB串口接到虚拟机&#xff0c;执行dmesg命令查看串口设备名&#xff1a; 测试&#xff1a; sudo screen /dev/ttyUSB0 115200确实很简单。

数据结构(五)——树森林

5.4 树和森林 5.4.1 树的存储结构 树的存储1&#xff1a;双亲表示法 用数组顺序存储各结点&#xff0c;每个结点中保存数据元素、指向双亲结点(父结点)的“指针” #define MAX_TREE_SIZE 100// 树的结点 typedef struct{ElemType data;int parent; }PTNode;// 树的类型 type…

【Godot4.2】像素直线画法及点求取函数

概述 基于CanvasItem提供的绘图函数进行线段绘制只需要直接调用draw_line函数就可以了。 但是对于可以保存和赋值节点直接使用的纹理图片&#xff0c;却需要依靠Image类。而Image类没有直接提供基于像素的绘图函数。只能依靠set_pixel或set_pixelv进行逐个像素的填色。 所以…