zoukankan      html  css  js  c++  java
  • [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;
    }
  • 相关阅读:
    ArrayList 和 Vector 的区别
    Redis在springboot中使用,读取字符串
    初始化Mysql
    Redis 安装
    React-脚手架
    React virtual DOM explained in simple English/简单语言解释React的虚拟DOM
    数据结构
    书单(18-19)
    算法复杂度
    otrs离线部署
  • 原文地址:https://www.cnblogs.com/mooba/p/7473262.html
Copyright © 2011-2022 走看看