【动态规划】路径问题

文章探讨了动态规划在解决不同路径问题(包括无/有障碍、最大价值和最小和)的应用,如Cefler博客中提到的几个编程题目,以及递归搜索方法在地下城游戏中的局限性及其替代的动态规划解决方案。
摘要由CSDN通过智能技术生成

在这里插入图片描述

欢迎来到Cefler的博客😁
🕌博客主页:那个传说中的man的主页
🏠个人专栏:题目解析
🌎推荐文章:题目大解析(3)

在这里插入图片描述


👉🏻不同路径I

原题链接:不同路径
在这里插入图片描述
在这里插入图片描述

mycode:

class Solution {
public:
  int uniquePaths(int m, int n) {
     
    vector<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];
}
};

👉🏻不同路径II

原题链接:不同路径II

mycode:

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int m = obstacleGrid.size(),n = obstacleGrid[0].size();
        vector<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];
            if(obstacleGrid[i-1][j-1]==1)
                dp[i][j] = 0;
        }
    }
    return dp[m][n];

    }
};

👉🏻礼物的最大价值

原题链接:珠宝的最高价值
在这里插入图片描述
在这里插入图片描述

mycode:

class Solution {
public:
    int jewelleryValue(vector<vector<int>>& frame) {
            int m = frame.size(),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-1][j]+frame[i-1][j-1],dp[i][j-1]+frame[i-1][j-1]);
            }
        }
    return dp[m][n];
    }
};

👉🏻下降路径最小和

原题链接:下降路径最小和

mycode:

class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) {
        //dp[i][j]:到该位置的最小路径和
        //dp[i][j] = dp[i][j] = min(min(dp[i-1][j-1]+matrix[i-1][j-1],dp[i-1][j]+matrix[i-1][j-1]),dp[i-1][j+1]+matrix[i-1][j-1]);
        //创建表
        int n = matrix.size();
        vector<vector<int>> dp(n,vector<int>(n));
        //初始化表
        for(int i = 0;i<n;i++) dp[0][i] = matrix[0][i];
        //从i = 1开始遍历
        for(int i = 1;i<n;i++)
        {
            for(int j = 0;j<n;j++)
            {
                //假设上方的最小路径和最小,然后再与左上和右上比较
                int Min = dp[i-1][j];
                //左上
                if(j-1>=0)
                    Min = min(Min,dp[i-1][j-1]);
                //右上
                if(j+1<n)
                    Min = min(Min,dp[i-1][j+1]);

                dp[i][j] = Min + matrix[i][j];
            }
        }
        //最后从n行(但dp表的下标为n-1)开始遍历找出最小的下降路径之和
        int min = 0;
        for(int i = 1;i<n;i++)
        {
            if(dp[n-1][i]<dp[n-1][min]) min = i;
        }
        return dp[n-1][min];
    }
};

👉🏻最小路径和

原题链接:最小路径和

mycode:

class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        //dp[i][j]:到该位置时的最小路径和
        //动态转移方程:dp[i][j] = min(dp[i-1][j]+grid[i][j],dp[i][j-1]+grid[i][j])
        int m = grid.size(),n = grid[0].size();
        vector<vector<int>> dp(m+1,vector<int>(n+1));
        //给第1行和第一列全部赋值为INT_MAX;但是dp[0][1]或者dp[1][0]赋值为0
        for(int i = 0;i<m+1;i++) dp[i][0] = INT_MAX;
        for(int i = 0;i<n+1;i++) dp[0][i] = INT_MAX;
        dp[0][1] = 0;dp[1][0] = 0;
        //开始填表
        for(int i = 1;i<m+1;i++)
        {
            for(int j =1;j<n+1;j++)
            {
               dp[i][j] = min(dp[i - 1][j] , dp[i][j - 1])+grid[i - 1][j - 1];
                //不能dp[i][j] = min(dp[i-1][j]+grid[i-1][j-1],dp[i][j-1]+grid[i-1][j-1]);因为INT_MAX+任何整数都会变为负数
            }
        }
        return dp[m][n];
    }
};

👉🏻地下城游戏

原题链接:地下城游戏
递归搜索方法(失败)
mycode:

class Solution {
public:
    //题目即求到最后位置时路径之和小于0的最大值
    //所以可以遍历得出所有的路径可能性,再存储所有1-路径可能性;返回其中>0&&最小值,如果全部小于0返回1
    vector<int> Sum;
  void dfs(vector<vector<int>>& dungeon, int i, int j, int sum)
{
    if (i == dungeon.size() - 1 && j == dungeon[0].size() - 1)
    {
        Sum.push_back(sum);
        return;
    }
    if (i < dungeon.size() - 1)
        dfs(dungeon, i + 1, j, sum + dungeon[i + 1][j]);
    if (j < dungeon[0].size() - 1)
        dfs(dungeon, i, j + 1, sum + dungeon[i][j + 1]);
}
int calculateMinimumHP(vector<vector<int>>& dungeon) {
    
    dfs(dungeon, 0, 0, dungeon[0][0]);
    vector<int> v;
    //存储所有1-路径可能性
    for(auto e:Sum)
        v.push_back(1-e);
    sort(v.begin(),v.end());

    for(int i = 0;i<v.size();i++)
    {
        if(v[i]>0) return v[i];
    }
     return 1;
}
};

该方法不行的原因的限制是:即该代码的理想情况是在抵达最后一个位置前都没考虑会死的情况

动态规划方法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
mycode:

class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& d) {
        int m = d.size(),n = d[0].size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,INT_MAX));
        //初始化
        dp[m][n-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] = min(dp[i+1][j],dp[i][j+1])-d[i][j];
                dp[i][j] = max(1,dp[i][j]);
            }
        }
        return dp[0][0];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值