小工具知识网

当前位置: 首页 > 行业知识 > 我在代码随想录|写代码Day33 | 动态规划| 路径问题| 62.不同路径,63. 不同路径 II,343. 整数拆分

行业知识

我在代码随想录|写代码Day33 | 动态规划| 路径问题| 62.不同路径,63. 不同路径 II,343. 整数拆分

2026-11-09 12:46:43 来源:互联网转载

博客介���`: 27dCnc

系列专栏: > >

当前专栏: >

专题 : 数据结构帮助小白快速入门算法

☆*: .。. o(≧▽≦)o .。.:*☆

❤️感谢大家点赞收藏⭐评论✍️

学习目标:

今日学习打卡

  • 代码随想录 - 动态规划

    学习时间:

    • 周一至周五晚上 7 点—晚上9点
    • 周六上午 9 点-上午 11 点
    • 周日下午 3 点-下午 6 点

      学习内容:

      1. 不同路径
      2. 不同路径 II
      3. 整数拆分

      内容详细:

      62.不同路径

      考点: 动态规划 数学 深度优先搜索(dfs)

      解题思路

      高中时候的组合规律,当然我们不能直接这样写我们要进行动态规划分析

      首先看到题目是想到dfs

      class Solution {private:    int dfs(int i, int j, int m, int n) {        if (i > m || j > n) return 0; // 越界了        if (i == m && j == n) return 1; // 找到一种方法,相当于找到了叶子节点        return dfs(i + 1, j, m, n) + dfs(i, j + 1, m, n);    }public:    int uniquePaths(int m, int n) {        return dfs(1, 1, m, n);    }};

      但是超时

      开始动态规划

      1. 确定dp数组以及下标的含义
      dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。
      1. 确定递推公式(到这一步的方式)

      想要求dp[i][j],只能有两个方向来推导出来,即dp[i - 1][j] 和 dp[i][j - 1]。

      此时在回顾一下 dp[i - 1][j] 表示啥,是从(0, 0)的位置到(i - 1, j)有几条路径,dp[i][j - 1]同理。

      那么很自然,dp[i][j] = dp[i - 1][j] + dp[i][j - 1],因为dp[i][j]只有这两个方向过来。

      1. dp数组的初始化

        这个就是高中的知识点

      for (int i = 0; i  
      1. 确定遍历顺序

        这里要看一下递推公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了。

      这样就可以保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值的。

      1. 举例推导dp数组

        最终代码

      class Solution {public:    int uniquePaths(int m, int n) {        int dp[m][n];        dp[0][0] = 0;        for (int i = 0; i  

      63. 不同路径 II

      题目考点: 动态规划

      解题思路

      和上一题一样,只是多了障碍物,可以直接跳过,

      如果遇到障碍物 continue

      if (obstacleGrid[i][j] == 1) {continue;}

      i 代码

      class Solution {public:    int uniquePathsWithObstacles(vector& obstacleGrid) {        int l,r;        int m =obstacleGrid.size();        int n = obstacleGrid[0].size();        int dp[m][n];        if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1){            return 0;        }        memset(dp,0,sizeof(dp));        for (int i = 0; i  

      ii 代码

      class Solution {public:    int uniquePathsWithObstacles(vector& obstacleGrid) {        if (obstacleGrid[0][0] == 1)            return 0;        vector dp(obstacleGrid[0].size());        for (int j = 0; j  

      343. 整数拆分

      题目考点: 动态规划

      解题思路

      可以拆分成多个数据对动态规划实行贪心,max就是贪心的具象化,(个人理解)

      其他步骤省,这里详细讲解

      • 确定递推公式

        可以想 dp[i]最大乘积是怎么得到的呢?

        其实可以从1遍历j,然后有两种渠道得到dp[i].

        一个是j * (i - j) 直接相乘。

        一个是j * dp[i - j],相当于是拆分(i - j),对这个拆分不理解的话,可以回想dp数组的定义。

        那有同学问了,j怎么就不拆分呢?

        j是从1开始遍历,拆分j的情况,在遍历j的过程中其实都计算过了。那么从1遍历j,比较(i - j) * j和dp[i - j] * j 取最大的。

        递推公式:

        dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

        也可以这么理解,j * (i - j) 是单纯的把整数拆分为两个数相乘,而j * dp[i - j]是拆分成两个以及两个以上的个数相乘。

        • 如果定义dp[i - j] * dp[j] 也是默认将一个数强制拆成4份以及4份以上了。

        • 所以递推公式:dp[i] = max({dp[i], (i - j) * j, dp[i - j] * j});

        • 那么在取最大值的时候,为什么还要比较dp[i]呢?

          因为在递推公式推导的过程中,每次计算dp[i],取最大的而已。

          class Solution {public:    int integerBreak(int n) {        if(n 

上一篇:买卖宝源码大揭秘,核心功能与独特魅力全解析

下一篇:服务器加硬盘怎么处理6?