动态规划 DP (二)

news2024/11/23 15:34:57

3.二维动态规划

1)

力扣icon-default.png?t=N5K3https://leetcode.cn/problems/minimum-path-sum/第一行的的路径只与左边的元素有关,第一列的路径只与上面的元素有关。

除了第一行和第一列,其他元素的路径取决于左边和上面元素的最小值。

只要每次都选择值最小的路径,最后得到的就是最小路径。

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        vector<vector<int>> path = grid;
        for(int i=1;i<n;i++){
            path[0][i] += path[0][i-1];
        }
        for(int i=1;i<m;i++){
            path[i][0] += path[i-1][0];
        }
        for(int i=1;i<m;i++){
            for(int j=1;j<n;j++){
                path[i][j] += min(path[i-1][j], path[i][j-1]);
            }
        }
        return path[m-1][n-1];
    }
};

上述代码用到了二维数组,为了空间压缩,可以只用一个一维数组:

path[j]表示二维数组中的path[i-1][j](未更新)

path[j-1]表示二维数组中的path[i][j-1](已更新)

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int m = grid.size();
        int n = grid[0].size();
        vector<int> path(n,0);

        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(i==0&&j==0){
                    path[j] = grid[i][j];
                }else if(i==0){
                    path[j] = path[j-1] + grid[i][j];
                }else if(j==0){
                    path[j] = path[j] + grid[i][j];
                }else{
                    path[j] = min(path[j],path[j-1]) + grid[i][j];
                }
            }
        }
        return path[n-1];
    }
};

2)

力扣icon-default.png?t=N5K3https://leetcode.cn/problems/01-matrix/当元素值为0时,最近距离就是0。

当元素值为1时,最近距离为周围四个元素的最近距离的最小值加1。

因为做BFS,最差时间复杂度为O(m*n*m*n)。

所以还是用DP记录最近距离速度会更快些。

很直观地能发现,先从左上往右下扫描,得到只考虑左边元素和上边元素时的最小距离。

再从右下往左上扫描,可以得到考虑右边元素和下边元素的最小距离。

做完两遍扫描,就把周围四个元素都考虑进去了。

时间复杂度为O(2*m*n)。

注意最小距离数组一开始要设置为最大距离减一

class Solution {
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
        int m = mat.size(), n = mat[0].size();
        vector<vector<int>> res(m,vector<int>(n,INT_MAX-1));

        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(mat[i][j]==0){            
                    res[i][j] = 0;
                }else{
                    if(i>0){
                        res[i][j] = min(res[i][j], res[i-1][j]+1);
                    }
                    if(j>0){
                        res[i][j] = min(res[i][j], res[i][j-1]+1);
                    }
                }
            }
        }


        for(int i=m-1;i>=0;i--){
            for(int j=n-1;j>=0;j--){
                if(res[i][j]){
                    if(i<m-1){
                        res[i][j] = min(res[i][j], res[i+1][j]+1);
                    }
                    if(j<n-1){
                        res[i][j] = min(res[i][j], res[i][j+1]+1);
                    }
                }
            }
        }
        
       
        return res;
    }
};

3)

力扣icon-default.png?t=N5K3https://leetcode.cn/problems/maximal-square/假设当前元素是正方形右下角的元素

若想要正方形边长为1,那么当前元素值为'1'就行了

若想要正方形变成为2,那么不仅要当前元素值为’1‘,还需要上边,左边,左上角三个元素分别所能构成的最大正方形边长>=1。

若想要正方形变成为3,那么不仅要当前元素值为’1‘,还需要上边,左边,左上角三个元素分别所能构成的最大正方形边长>=2。

依此类推,得到状态转移方程:

dp[i][j] = 1 + min(dp[i-1][j],min(dp[i][j-1], dp[i-1][j-1]))

每次记录边长最长的值,最终就能得到最大正方形的面积。

class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        int m = matrix.size();
        int n = matrix[0].size();
        int res = 0;
        vector<vector<int>> dp(m,vector<int>(n,0));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(i==0||j==0){
                    dp[i][j] = matrix[i][j]-'0';
                    res = max(res, dp[i][j]);
                }else{
                    if(matrix[i][j]=='1'){
                        dp[i][j] = 1 + min(dp[i-1][j],min(dp[i][j-1], dp[i-1][j-1]));
                        res = max(res, dp[i][j]);
                    }
                }
            }
        }
        return res*res;
    }
};

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

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

相关文章

2021电工杯数学建模B题解题思路(光伏建筑一体化板块指数发展趋势分析及预测)

目录 一、前言 二、问题背景 三、具体问题 四、解题思路 &#xff08;一&#xff09;整体思路 &#xff08;二&#xff09;问题一 &#xff08;三&#xff09;问题二 &#xff08;四&#xff09;问题三 &#xff08;五&#xff09;问题四 &#xff08;六&#xff09;…

2023最新谷粒商城笔记之秒杀服务篇(全文总共13万字,超详细)

秒杀服务 秒杀具有瞬间高并发的特点&#xff0c;针对这一特点&#xff0c;必须要做限流异步缓存(页面静态化)独立部署 限流方式&#xff1a; 前端限流&#xff0c;一些高并发的网站直接在前端页面开始限流&#xff0c;例如&#xff1a;小米的验证码设计Nginx 限流&#xff0c…

ChatGPT从入门到精通,深入认识Prompt

ChatGPT从入门到精通&#xff0c;一站式掌握办公自动化/爬虫/数据分析和可视化图表制作 全面AI时代就在转角 道路已经铺好了 “局外人”or“先行者” 就在此刻 等你决定让ChatGPT帮你高效实现职场办公&#xff01;行动起来吧1、ChatGPT从入门到精通&#xff0c;一站式掌握办公…

Unity 中的旋转、targetFrameRate、 vSyncCount、Time

1. 旋转&#xff1a; Unity 中的旋转用eulerAngle 表示&#xff0c;但在内部是以quaternion存储。欧拉角旋转围绕三个轴进行三次独立旋转&#xff0c;依次是z、x、y。To convert from Euler angles to quaternions, you can use the Quaternion.Euler function.To convert a q…

Linux 文件操作

文章目录 一、task_struct 和 file 的关系二、文件操作的系统调用三、进程默认打开的三个文件四、文件重定向五、Linux 下一切皆文件 文件是在磁盘上创建出来的&#xff0c;当我们想进行文件操作时&#xff0c;根据冯诺依曼体系结构&#xff0c;CPU 只和内存交互&#xff0c;为…

【裸机开发】Reset 中断服务函数(汇编实现)

目录 一、Reset 中断服务函数的实现步骤 二、汇编实现 Reset 中断服务函数 1、禁止/打开全局中断 2、设置SP指针 3、清除 .bss 段 4、完整 Reset 中断服务函数 一、Reset 中断服务函数的实现步骤 实现 Reset 中断服务函数的基本步骤如下&#xff1a; 设置各个模式下的S…

关联式容器set和map

文章目录 一.容器二.set的介绍1.insert2.lower_bound&&upper_bound3.find和countfindcount 三. multiset四.map最特别的operator[] 四.multimap&#xff0c;因为允许键值冗余&#xff0c;所以它没有operator[]&#xff0c;它的find返回的是中序遍历第一次遇到的节点五.…

ChatGPT办公自动化实战

ChatGPT从入门到精通&#xff0c;一站式掌握办公自动化/爬虫/数据分析和可视化图表制作 全面AI时代就在转角 道路已经铺好了 “局外人”or“先行者” 就在此刻 等你决定 让ChatGPT帮你高效实现职场办公&#xff01;行动起来吧 1、ChatGPT从入门到精通&#xff0c;一站式掌握办…

对象的销毁

析构函数 C 中的类可以定义一个特殊的清理函数 这个特殊的清理函数叫做析构函数析构函数的功能与构造函数相反 定义&#xff1a;~ClassName() 析构函数没有参数也没有返回值类型声明析构函数在对象销毁时自动被调用 析构函数使用初探 #include <stdio.h>class Test …

Threadlocal 必会的9个知识点

1.什么是ThreadLocal&#xff1f;它在多线程环境下有什么用处&#xff1f; ThreadLocal是在多线程环境下提供的一种简单的机制&#xff0c;使得每个线程都能拥有一个独立的变量副本。它避免了线程安全问题&#xff0c;并提高了程序的并发性能。 2.ThreadLocal是如何工作的&am…

规则引擎--规则逻辑形如“1 (2 | 3)“的抽象设计

目录 规则下逻辑表达和条件的抽象表达逻辑的编码和抽象 规则规则下的条件操作符抽象定义规则类规则执行表达式遍历进行操作符计算添加规则下一个具体条件的执行 规则执行完成后得到最后的结果 规则下逻辑表达和条件的抽象 对于任何一个规则&#xff0c;当然包括多个条件&#…

市面上最强PDF:GcPDF 6.1.4 Grapecity -Crack

适用于 .NET 6 的功能丰富的 PDF API 库 完全控制 PDF - 快速生成文档、提高内存效率且无依赖性。 在代码中生成、加载、编辑和保存 PDF 文档 支持多种语言的全文、段落格式和字体 使用新的编辑工具编辑 PDF 中的内容 支持数百种PDF功能 Windows、macOS 和 Linux 完全支持所有…

PhotoShop Beta(爱国版)安装教程-内置AI绘画功能

PS beta版安装教程 Window和Mac版都有&#xff0c;里面内置AI绘画功能 ps Beta版真的太爽了&#xff0c;今天来和大家分享下安装教程。 很多人拿这资料卖5块 9.9 19.9&#xff0c;球友们直接用&#xff0c;建议赶紧装&#xff0c;以免PS更新后&#xff0c;很多pojie程序没法用了…

ChatGPT数据分析与可视化实战

ChatGPT从入门到精通&#xff0c;一站式掌握办公自动化/爬虫/数据分析和可视化图表制作 全面AI时代就在转角 道路已经铺好了 “局外人”or“先行者” 就在此刻 等你决定 让ChatGPT帮你高效实现职场办公&#xff01;行动起来吧1、ChatGPT从入门到精通&#xff0c;一站式掌握办…

docker安装drone

目录 Drone简介docker安装drone创建Drone-server容器创建Drone-runner-docker容器 访问drone-server面板操作 Drone简介 Drone是基于GO语言开发的持续集成&#xff08;Continuous integration&#xff0c;CI&#xff09;引擎&#xff0c;它可以借助Docker容器技术&#xff0c;…

Autosar RTE C/S接口实现及synchronous与asynchronous的区别

文章目录 前言Server接口设计server接口Simulink实现server函数mapping Function生成的代码 Client接口设计Client接口Simulink实现ClientFunction Caller Mapping生成的代码Rte_CallRte_Result 总结 前言 在之前的一篇文章中&#xff0c;介绍了RTE中的S/R接口&#xff0c;也是…

(一)WPF - WPF

一、Window 图形演化 创建用户界面&#xff1a; User32&#xff1a; 该部分为许多元素&#xff08;如窗口、按钮和文本框等&#xff09;提供了熟悉的 Windows 外观。GDI/GDI&#xff1a; 该部分为渲染简单形状、文本以及图像提供了绘图支持&#xff0c;但增加了复杂程度&…

Nginx使用

说明&#xff1a;Nginx是静态资源服务器&#xff0c;可以部署静态资源&#xff0c;并对请求进行策略分发。 下载 第一步&#xff1a;可在官网&#xff08;http://nginx.org/en/download.html&#xff09;下载&#xff0c;建议安装稳定版本&#xff08;Stable version&#xf…

【力扣刷题 | 第十三天】

前言&#xff1a; 今天随机进行练习&#xff0c;题型上不会有什么限制&#xff0c;主要还是练习STL算法。 88. 合并两个有序数组 - 力扣&#xff08;LeetCode&#xff09; 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分…