【动态规划】状态 dp

news2024/10/11 10:21:43

在这里插入图片描述

动态规划步骤: 

  1. 状态表示。所谓状态表示就是 dp 表里的值表示什么含义,那么状态表示怎么找呢? a. 题目要求 b. 经验(以某一个位置为结尾 / 起点) + 题目要求 c. 分析问题的过程中发现重复子问题
  2. 状态转移方程。dp[ i ] 等于什么
  3. 初始化。保证填表的时候不越界
  4. 填表顺序。保证填写当前状态时,所需要的状态已经计算过了,初始化之后,下标的映射关系要一致
  5. 返回值。根据题目要求和状态表示进行返回

1. 不同路径

62. 不同路径

状态表示:以 dp[i][j] 为结尾,走到 dp[i][j] 位置时一共有几种方式

状态转移方程:

走到 (i , j) 位置时,它只可能是从上面的格子和左边的格子过来的,走到这两个格子之后再走一步就到 (i , j) 了,所以走到 (i, j) 位置的方式就是把走到上面的格子和左边的格子的方案数加起来,也就是 dp[i - 1][j] + dp[i][j - 1]

初始化:填 dp 表的时候,由于需要用到上边和左边的格子,填最上面的一行和最左边的一列时会越界,为了避免越界可以把 dp 表多开一列和一行,并且根据题目要求把这一行和一列赋上合适的值,以此确保能够正确的对 dp 表进行赋值

填表顺序:从上往下,从左到右

返回值:多开一行和一列之后返回的就是 dp[m][n],也就是要求的走到这个位置的方案数

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m + 1][n + 1];
        dp[0][1] = 1;
        for (int i = 1; i < dp.length; i++) {
            for (int j = 1; j < dp[0].length; j++) {
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
            }
        }
        return dp[m][n];
    }
}

2. 不同路径 II

63. 不同路径 II

这题和上一题不同的就是加入了障碍物

状态表示:以 dp[i][j] 为结尾,走到 dp[i][j] 位置时一共有几种方式

状态转移方程:

还是和上一道题一样,走到 (i , j) 位置时,它只可能是从上面的格子和左边的格子过来的,如果说有障碍物的时候,那么走到那个格子的方案数就是 0 ,如果 (i , j) 位置本身就是障碍物,也就是无论哪个格子都不能到达,dp[i][j] 也就是 0 ,其它情况正常相加即可

初始化:和上一题一样

填表顺序和返回值都和上一题一样

下标的映射关系需要注意一下,由于这题在填 dp 表的时候需要判断当前位置是否是障碍物,所以需要通过遍历 arr 的下标进行填表,由于 dp 表多开了一行和一列,所以填表的时候下标都需要加一,或者是遍历 dp 表的下标,对 arr 进行减一

class Solution {
    public int uniquePathsWithObstacles(int[][] arr) {
        int[][] dp = new int[arr.length + 1][arr[0].length + 1];
        dp[0][1] = 1;
        for(int i = 0;i < arr.length;i++){
            for(int j = 0;j < arr[0].length;j++){
                if(arr[i][j] == 1){
                    dp[i+1][j + 1] = 0;
                }else{
                    dp[i + 1][j + 1] = dp[i][j + 1] + dp[i + 1][j];
                }
            }
        }
        return dp[arr.length][arr[0].length];
    }
}

3. LCR 166. 珠宝的最高价值

LCR 166. 珠宝的最高价值

状态表示:到达 (i , j) 位置时可以获得珠宝的最大值

状态转移方程:其实和上面的题都非常类似,只能从上边的格子和左边的格子到达 (i , j) 位置,取这两个的最大值再加上 (i , j) 位置的价值即可

初始化:也和前面类似,为了不影响原来的值,把多开的一行和一列全设为 0 就行,同时也需要注意下标的映射关系

填表顺序:从上到下,从左到右

返回值:dp[m][n]

class Solution {
    public int jewelleryValue(int[][] frame) {
        int m = frame.length,n = frame[0].length;
        int[][] dp = new int[m + 1][n + 1];
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                dp[i + 1][j + 1] = Math.max(dp[i][j + 1],dp[i + 1][j]) + frame[i][j];
            }
        }
        return dp[m][n];
    }
}

4. 931. 下降路径最小和

931. 下降路径最小和

状态表示:dp[i][j] 表示到达 (i , j) 时的下降路径最小和

状态转移方程:(i , j) 位置只能由上面的位置和左上,右上的位置到达,求出三者的最小值再加上当前位置的值就是当前位置的路径最小和

初始化:这次初始化所用到的数据就需要额外再多开一行和两列,

填表顺序:从上往下

返回值:最后一行的最小值

class Solution {
    public int minFallingPathSum(int[][] matrix) {
        int m = matrix.length,n = matrix[0].length + 1;
        int[][] dp = new int[m + 1][n + 1];
        for(int i = 1;i < m + 1;i++){
            dp[i][0] = dp[i][n] = Integer.MAX_VALUE;
        }
        for(int i = 0;i < m;i++){
            for(int j = 0;j < matrix[0].length;j++){
                dp[i+1][j+1] = Math.min(Math.min(dp[i][j],dp[i][j + 1]),dp[i][j + 2]) + matrix[i][j];
            }
        }
        int res = Integer.MAX_VALUE;
        for(int i = 1;i < n;i++){
            res = Math.min(res,dp[m][i]);
        }
        return res;
    }
}

5. 最小路径和

64. 最小路径和

这一题和珠宝最大和是非常相似的,不过就是这里要求最小的路径和

状态表示:dp[i][j] 表示到达 (i , j) 时的最小路径和

状态转移方程:

初始化:

返回值:dp[m][n]

class Solution {
    public int minPathSum(int[][] grid) {
        int m = grid.length,n = grid[0].length;
        int[][] dp = new int[m + 1][n + 1];
        for(int i = 0;i < m + 1;i++){
            for(int j = 0;j < n + 1;j++){
                dp[i][j] = Integer.MAX_VALUE;
            }
        }
        dp[1][0] = dp[0][1] = 0;
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                dp[i+1][j + 1] = Math.min(dp[i + 1][j],dp[i][j+1]) + grid[i][j];
            }
        }
        return dp[m][n];
    }
}

6. 地下城游戏

174. 地下城游戏

状态表示:根据之前的经验就是以 (i , j) 位置为结尾或者为开始

先来看以 (i , j) 位置为结尾的方式,此时就是从起点出发,到达 (i , j) 所需的最低初始健康点数,但是这个点的值还会受到右边和下边的影响的,如果说再走到右边或者下边就死了那这个健康点数就不对,所以这种方式退不出状态转移方程

接下来看另一种方式,以(i , j) 位置为开始到达终点所需的最低初始健康点数

假设 dp[i][j] = x,如果说接下来可以走到右边或者下边,那么就需要令 x + dungeon[i][j] 的值大于右边或者下边的 dp 值,也就是从这个位置出去之后的血量需要大于下一步所需的最低健康点数,由于是最低,那么就不用是大于了,等于就可以了,接下来再求出是右边所需最低还是下边所需最低即可

但是结果可能会是一个负数,如果说当前位置回了一大口血,超过了下一步所需的最低血量,那么减出来的就是负数,也就是 dp[i][j] 是一个负数加上回的血 dungeon 就能通过,这是不合理的,所以当是负数的话就设置为 1

初始化:这次受到影响的是最后一行和最右边的一列

填表顺序:由于填 dp[i][j] 的时候需要用到右边和下边的值,所以需要先从右往左,再从下往上

返回值:返回 dp[0][0] 即可

class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
        int m = dungeon.length, n = dungeon[0].length;
        int[][] dp = new int[m + 1][n + 1];
        for (int j = 0; j < dp[0].length; j++) {
            dp[m][j] = Integer.MAX_VALUE;
        }
        for (int i = 0; i < dp.length; i++) {
            dp[i][n] = Integer.MAX_VALUE;
        }
        dp[m][n - 1] = 1;
        dp[m - 1][n] = 1;
        for (int i = m - 1; i >= 0; i--) {
            for (int j = n - 1; j >= 0; j--) {
                dp[i][j] = Math.min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j];
                dp[i][j] = Math.max(1, dp[i][j]);
            }
        }
        return dp[0][0];
    }
}

在这里插入图片描述

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

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

相关文章

<Project-8.1 pdf2tx-MM> Python Flask 用浏览器翻译PDF内容 2个翻译引擎 繁简中文结果 从P8更改

更新 Project Name&#xff1a;pdf2tx (P6) Date: 5oct.24 Function: 在浏览器中翻译PDF文件 Code:https://blog.csdn.net/davenian/article/details/142723144 升级 Project Name: pdf2tx-mm (P8) 7oct.24 加入多线程&#xff0c;分页OCR识别&#xff0c;提高性能与速度 使…

美发店管理革新:SpringBoot系统的应用

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理美发门店管理系统的相关信息成为必然。开发…

3D生成基础模型来了!只需5秒,高质量3D资产规模化生成!南洋理工等重磅开源3DTopia-XL

文章链接&#xff1a;https://arxiv.org/pdf/2409.12957 项目链接&#xff1a;https://3dtopia.github.io/3DTopia-XL/ 今天AI生成未来和大家分享的是南洋理工、北大、上海AI Lab和港中文联合发布的3D PBR资产生成最新工作3DTopia-XL。通过基于高效且表达力强的3D表示方法Pri…

Vue3 集成Monaco Editor编辑器

Vue3 集成Monaco Editor编辑器 1. 安装依赖2. 使用3. 效果 Monaco Editor &#xff08;官方链接 https://microsoft.github.io/monaco-editor/&#xff09;是一个由微软开发的功能强大的在线代码编辑器&#xff0c;被广泛应用于各种 Web 开发场景中。以下是对 Monaco Editor 的…

【linux 多进程并发】0201 Linux进程fork内存空间,父子进程变量内存地址居然是一样的

0201 Linux进程fork方式详解 ​专栏内容&#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 文章…

学习记录:js算法(五十七):二叉树中所有距离为 K 的结点

文章目录 二叉树中所有距离为 K 的结点思路一思路二 二叉树中所有距离为 K 的结点 给定一个二叉树&#xff08;具有根结点 root&#xff09;&#xff0c; 一个目标结点 target &#xff0c;和一个整数值 k &#xff0c;返回到目标结点 target 距离为 k 的所有结点的值的数组。&…

matlab002

新建工程test001 例如&#xff1a; 脚本&#xff08;Script&#xff09; 概念 脚本是一系列按顺序执行的 MATLAB 命令的集合。它就像是一个记录了你在命令行中输入的一系列指令的文件。用途 适用于简单的任务&#xff0c;例如数据处理、可视化等一次性的操作。例如&#xff0c…

重学SpringBoot3-集成Redis(四)之Redisson

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;四&#xff09;之Redisson 1. 添加 Redisson 依赖2. 配置 Redisson 客户端3. 使用 Redisson 实现分布式锁4. 调用分布式锁5. 为什…

Java 获取热搜并生成图片

效果图如下&#xff1a; 第一步获取热搜 public List<String> getHotNews4(Integer size) {if (size < 0 || StringUtils.isEmpty(size)) {return null;}try {//set 转listreturn new ArrayList<>(getHotNews(size));} catch (Exception e) {logger.error(&qu…

如何基于审批实现文件外发管控,阻断数据违规外流?

FTP可以说是实际中企业运用最广泛的文件传输方式&#xff0c;很多企业不仅内部传输文件使用FTP&#xff0c;在与外部合作伙伴协作时&#xff0c;也多采用FTP进行文件的外发和收取。例如半导体行业&#xff0c;默认的都是使用FTP进行文件外发&#xff0c;这时候&#xff0c;替换…

卷积神经网络细节问题及知识点

一、Batch Normalization Batch Normalization&#xff08;BN&#xff0c;批归一化&#xff09; 是深度学习中的一种技术&#xff0c;主要用于加速神经网络的训练过程&#xff0c;同时提高网络的稳定性和收敛速度。它通过对每一层的输出进行归一化&#xff0c;减少梯度消失和梯…

本地部署Docsify生成文档网站并实现公网环境远程访问

文章目录 前言1. 本地部署Docsify2. 使用Docsify搭建个人博客3. 安装Cpolar内网穿透工具4. 配置公网地址5. 配置固定公网地址 前言 本文主要介绍如何在Windows环境本地部署 Docsify 这款以 markdown 为中心的文档编辑器&#xff0c;并即时生成您的文档博客网站&#xff0c;结合…

ubuntu22.04 安装wine9.0 全网首发

wine官网推荐安装方式&#xff1a;https://gitlab.winehq.org/wine/wine/-/wikis/zh_CN/Debian-Ubuntu 博主按照这种方式是失败的&#xff0c;虽然开启了“低调上网”&#xff0c;貌似代理对于终端不起作用&#xff0c;后面会介绍替代方案&#xff0c;一样完美。 一、官网的安…

Pycharm里设置关于designer.exe以及pyuic5.exe的外部工具

文章目录 1.Pycharm与Pyuic5介绍(1)Pycharm(2)Pyuic5 2.Pycharm里设置外部工具(1)切换到外部工具(2)designer创建外部工具(3)pyuic5创建外部工具(4)使用designer和pyuic5 3.本章总结 1.Pycharm与Pyuic5介绍 (1)Pycharm Pycharm是专门用于python编程语言的编辑软件&#xff0c;…

QT的核心机制 对话框资源

案例 1、键盘按下w&#xff0c;s&#xff0c;a&#xff0c;d键分别为标签向上&#xff0c;下&#xff0c;左&#xff0c;右移动 鼠标按下获取本地坐标&#xff0c;全局坐标 鼠标双击获取本地坐标&#xff0c;全局坐标 鼠标移动获取本地坐标&#xff0c;全局坐标 让鼠标跟踪…

C语言 ——— oj题:有效的括号

目录 题目要求 代码实现 题目要求 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个…

【靶点Talk】为什么联合用药喜欢用VEGF+VEGFR?

血管生成对肿瘤发生、发展的重要影响的发现&#xff0c;使肿管生成变为肿瘤研究的热点之一。今天给大家带来VEGF、VEGFR相关介绍&#xff0c;更多靶点科普视频请关注义翘神州B站和知乎官方账号。 1、VEGFR的“简历” VEGFR包括VEGFR-1、VEGFR-2和VEGFR-3。VEGFR-2可与多种VEGF…

leetcode hot100_part03_滑动窗口

滑动窗口是有一个基本的模版的&#xff0c;不要自己想当然哦~ 滑动窗口算法思想&#xff08;附经典例题&#xff09;_滑动窗口的思想-CSDN博客 滑动窗口也叫同向双指针&#xff1b;可以先看一下灵山视频&#xff1a;滑动窗口【基础算法精讲 03】_哔哩哔哩_bilibili 3.无重复字…

springboot如何自动生成mybatis映射文件、dao、pojo层文件?

背景&#xff1a;以前一直是直接cv一个项目中现成的xml文件&#xff0c;然后再去自己配置mapper等数据。自己准备做一个单独的例子试一下。 步骤1&#xff1a;在pom.xml文件中插入mybatis-generator插件&#xff0c;这里选的版本是1.3.2&#xff0c;然后指定的generator文件是在…

ChatGPT 4o with Canvas — 新特性详解

# ChatGPT 4o with Canvas — 新特性详解 最近猫哥也感受到 Canvas 的强大&#xff0c;顺手开了个会员体验了一天&#xff0c;今天给大家简单分享一下&#xff0c;有想体验的伙伴可以文末名片私信我哈&#xff01; 关键词&#xff1a; #ChatGPT4o #Canvas新特性 #AI写作工具 …