【动态规划算法练习】day3

文章目录

  • 一、931. 下降路径最小和
    • 1.题目简介
    • 2.解题思路
    • 3.代码
    • 4.运行结果
  • 二、64. 最小路径和
    • 1.题目简介
    • 2.解题思路
    • 3.代码
    • 4.运行结果
  • 三、面试题 17.16. 按摩师
    • 1.题目简介
    • 2.解题思路
    • 3.代码
    • 4.运行结果
  • 总结


一、931. 下降路径最小和

1.题目简介

931. 下降路径最小和
题目描述:
给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径的最小和 。
下降路径可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) 。
【动态规划算法练习】day3_第1张图片
【动态规划算法练习】day3_第2张图片
【动态规划算法练习】day3_第3张图片
【动态规划算法练习】day3_第4张图片

2.解题思路

这道题要求下降路径的最小和,即从第一行到最后一行的所有路径的最小和。
根据动态规划的五步解题思路:

3.代码

具体代码如下(C++):

class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& matrix) {
        vector<int> v(matrix[0].size(), 0);
        vector<vector<int>> dp(matrix.size(), v);
        for(int j = 0;j < matrix[0].size(); ++j)
        {
            dp[0][j] = matrix[0][j];
        }
        for(int i = 1;i < matrix.size(); ++i)
        {
            for(int j = 0;j < matrix[0].size(); ++j)
            {
                if(j == 0)
                {
                    dp[i][j] = min(dp[i - 1][j], dp[i - 1][j + 1]) + matrix[i][j];
                }
                else if(j == (matrix[0].size() - 1))
                {
                    dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1]) + matrix[i][j];
                }
                else
                {
                    dp[i][j] = min(min(dp[i - 1][j], dp[i - 1][j - 1]), dp[i - 1][j + 1]) + matrix[i][j];
                }
            }
        }
        int ret = INT_MAX;
        for(int j = 0;j < matrix[0].size(); ++j)
        {
            ret = min(ret, dp[matrix.size() - 1][j]);
            cout<<j<<":"<<dp[matrix.size() - 1][j]<<endl;
        }
        return ret;
    }
};

4.运行结果

【动态规划算法练习】day3_第5张图片

二、64. 最小路径和

1.题目简介

64. 最小路径和
题目描述:
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
【动态规划算法练习】day3_第6张图片
【动态规划算法练习】day3_第7张图片

2.解题思路

这道题要求最小路径和,可以化简为求从左上角到路径中某个格子的最小路径和,然后再计算从左下角到右下角的最小路径和。
根据动态规划的五步解题思路:
【动态规划算法练习】day3_第8张图片

3.代码

具体代码如下(C++):

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

4.运行结果

【动态规划算法练习】day3_第9张图片

三、面试题 17.16. 按摩师

1.题目简介

题目描述:
面试题 17.16. 按摩师
一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
【动态规划算法练习】day3_第10张图片

2.解题思路

这道题要求按摩师最大工作分钟数,可以计算每一个预约中按摩师接不接该预约的最大分钟数,然后最终计算所有的预约最大分钟数(根据具体情况,有时候不接当前预约反而可以获得更大的工作时间)
根据动态规划的五步解题思路:
【动态规划算法练习】day3_第11张图片

3.代码

具体代码如下(C++):

class Solution {
public:
    int massage(vector<int>& nums) {
        if(nums.size() == 0) return 0;
        vector<int> v(2, 0);
        vector<vector<int>> dp(nums.size(), v);
        dp[0][0] = 0;
        dp[0][1] = nums[0];
        for(int i = 1;i < nums.size(); ++i)
        {
            dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);
            dp[i][1] = dp[i - 1][0] + nums[i];
        }
        return max(dp[nums.size() - 1][0], dp[nums.size() - 1][1]);
    }
};

4.运行结果

【动态规划算法练习】day3_第12张图片


总结

今天是算法练习的第3天。
不积跬步,无以至千里;不积小流,无以成江海。继续加油!
如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!
文中练习到的所有题目均来源于Leetcode网站,大家可以去原网站进行练习(直接点击题目链接即可)。

你可能感兴趣的:(动态规划-算法练习,算法,动态规划,leetcode)