[DP]矩阵的最小路径和

题目

给定一个矩阵m, 从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的树子累加起来就是路径和,返回所有的路径中最小的路径和.

解法一

这是一道经典的动态规划题,状态转移方程为dp[i][j] = min{dp[i - 1][j], dp[i][j - 1]} + m[i][j].可以用一个二维的dp矩阵来求解.对于dp矩阵,第一行和第一列只会有一种走法,就是从左到右或者从上到下的累加,所以可以先进行初始化,然后其他元素就可以用过转移方程一个一个填充,知道把整个dp矩阵填充完毕.

解法二

如果用二维数组,对于m行n列的数组,空间复杂度就是O(m*n).动态规划中常用的优化方法之一就是仅使用一个一维数组在进行这个迭代过程.但是这种空间压缩也有局限性,那就是不能记录获得最后结果的路径.如果需要完整路径的话还是需要二维的动态规划表.

代码

#include <iostream>
#include <vector>

using namespace std;
//使用二维数组的方式
int minPathSum1(int arr[4][4], int m, int n) {
    if (m == 0 || n == 0)
        return 0;
    int dp[m][n];
    dp[0][0] = arr[0][0];
    for (int i = 1; i < m; i ++)
        dp[i][0] = dp[i - 1][0] + arr[i][0];
    for (int j = 1; j < n; j ++)
        dp[0][j] = dp[0][j - 1] + arr[0][j];

    for (int i = 1; i < m; i ++) {
        for (int j = 1; j < n; j ++)
            dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + arr[i][j];
    }

    // print array
//    for (int i = 0; i < 4; i ++) {
//        for (int j = 0; j < 4; j ++)
//            cout<<dp[i][j]<<" ";
//        cout<<endl;
//    }

    return dp[m - 1][n - 1];
}

//使用一维数组的方式
int minPathSum2(int arr[4][4], int m, int n) {
    if (m == 0 || n == 0)
        return 0;
    int dp[n];
    dp[0] = arr[0][0];
    for (int k = 1; k < n; k ++)
        dp[k] = dp[k - 1] + arr[0][k];

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

    //print dp array
//    for (int k = 0; k < n; k ++)
//        cout<<dp[k]<<" ";
//    cout<<endl;

    return dp[n - 1];
}

int main()
{
    int arr[4][4] = {{1,3,5,9},{8,1,3,4},{5,0,6,1},{8,8,4,0}};

    for (int i = 0; i < 4; i ++) {
        for (int j = 0; j < 4; j ++)
            cout<<arr[i][j]<<" ";
        cout<<endl;
    }

    cout<<minPathSum2(arr, 4, 4)<<endl;
    return 0;
}
时间: 2024-10-08 13:02:03

[DP]矩阵的最小路径和的相关文章

【动态规划专题】2:矩阵的最小路径和

<程序员代码面试指南--IT名企算法与数据结构题目最优解> 左程云 著 矩阵的最小路径和 [题目]给定一个矩阵m,从左上角开始每次只能向右或者向下走,最后到达右下角位置,路径上所有的数字累加起来就是路径和,返回所有路径中最小的路径和. [举例]如果给定的m如下:1 3 5 98 1 3 45 0 6 18 8 4 0路径1,3,1,0,6,1,0是所有路径中路径和最小的,所以返回12. 关键思路:假设有一个M*N的数组 dp[M][N], dp[i][j]的值表示从左上角(0,0)位置走到(i

矩阵的最小路径和二维动态规划的空间压缩

题目:给定一个矩阵,从左上角开始每次只能向右或者向下移动,最后到达右下角的位置,路径上的所有的数字累加起来作为这条路径的路劲和.要求返回所有路径和中的最小路径和. 举例: 路径1,3,1,0,6,1,0是所有路径中路径和最小的,所以返回其和12. 解析: 这个题目很类似之前的那个动态规划的数字三角的问题.毫无疑问的,这个问题也是用动态规划解决.只要确定了状态和转移方程,这个题目很容易解决.下面直接给出代码: //利用path记录路径,对于每一个path[i][j],0代表dp[i][j]的值从上

矩阵的最小路径和

给你一个数组,求从[0,0]位置到[n-1,m-1]的最短路径. 数组如图所示: 1 3 5 9 8 2 3 4 5 0 6 1 8 8 4 0 路径1→3→1→0→6→1→0是所有路径中路径和最小的,所以返回12 代码: public class MinpathSum{ //时间复杂度O(M*N),空间复杂度O(M*N) public static int minPathSum1(int[][] matrix) { if(matrix == null || matrix.length==0 |

4.2 矩阵的最小路径和

[题目]: 给定一个矩阵m,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,返回所有路径和中最小的路径和 举例: 如果给定的m如下: 1      3      5      9 8      1      3      4 5      0      6      1 8      8      4      0 路径1,3,1,0,6,1,0是所有路径中路径和最小的,所以返回12 原文地址:https://www.cnblogs.com/latu

Light OJ 1406 Assassin`s Creed 状态压缩DP+强连通缩点+最小路径覆盖

题目来源:Light OJ 1406 Assassin`s Creed 题意:有向图 派出最少的人经过全部的城市 而且每一个人不能走别人走过的地方 思路:最少的的人能够走全然图 明显是最小路径覆盖问题 这里可能有环 所以要缩点 可是看例子又发现 一个强连通分量可能要拆分 n最大才15 所以就状态压缩 将全图分成一个个子状态 每一个子状态缩点 求最小路径覆盖 这样就攻克了一个强连通分量拆分的问题 最后状态压缩DP求解最优值 #include <cstdio> #include <cstri

矩阵中的最小路径

package 数阵中的最优路径; import java.util.Scanner; public class Main2 { /** * 数阵中的最小路径搜索 * 1:设计要点 * 应用动态规划设计从右下角逐行至左上角,确定n,m后,随机产生的整数二维数组a(n,m)作矩阵输出同时赋值给部分和数组b(n,m). * 数组b(i,j)为点(i,j)到到右下角的最小数值和stm(i,j)是点(i,j)向右(R)或向下(D)或向右下(0)的路标数组 * 注意到最后一行与最后一列各数只有一个出口,于

代码题(34)— 矩阵最小路径和

1.64. 最小路径和 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [   [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小. 需要用动态规划Dynamic Programming来做,这应该算是DP问题中比较简单的一类,我们维护一个二维的dp数组,其中dp[i][j]表示当前位置的最小路径和,递推式也容易写出来 

【数据结构与算法】动态规划——最小路径和(普通矩阵、三角形两题)

最小路径和 LeetCode:最小路径和 题目描述: 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [ [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小. 思想: 动态规划,可以用原数组作为dp数组 代码: class Solution { public int minPathSum(int[][] grid) {

算法52-----矩阵最小路径【动态规划】

一.题目:矩阵最小路径 给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入: [   [1,3,1], [1,5,1], [4,2,1] ] 输出: 7 解释: 因为路径 1→3→1→1→1 的总和最小. 思路1:时间O(M*N),空间O(M*N) 新建一个矩阵dp(大小也是M*N),该矩阵是从上往下,从左往右记录每一步的结果的,当前的结果可以根据该矩阵上面和左边最小的值来获得,即: dp[