当前位置: 首页 > news >正文

算法第29天|动态规划dp2:不同路径、不同路径Ⅱ、整数拆分、不同的二叉搜索树

今日总结:

        1、动态规划的五部曲:

                (1)确定动态规划数组dp[]的含义,确定dp[]数组的下标的含义

                (2)确定动态规划的递推公式

                (3)确定动态规划的初始化条件

                (4)确定动态规划的传播方向

                (5)举例论证递推公式的正确

        2、不同路径Ⅱ(需要重新思考)

                要注意障碍所在的多种位置:第一行第一列、起点终点、普通中间网格

        3、整数拆分(需要重新思考)

                注意对于整数差分获得乘积的最大的几种情况

                        1、拆分成两个后的乘积就是最大值

                        2、拆分成两个后,还需要对第二个数进行拆分

                遍历的时候,其实将j遍历到i/2即可,因为剩余的已经相当于遍历过了

不同路径

题目链接:62. 不同路径 - 力扣(LeetCode)

代码随想录

整体思路:

        从左上到右下:所有的位置(i,j)只能通过向下移动、向右移动,进行到达,所以位置(i.j)与之前状态(i-1,j),(i,j-1)相关,是动态规划的问题。

        1、确定动态规划的dp数组含义以及下标含义

                dp[i][j]的含义是到达当前位置有多少条路径

                i是横坐标,j是纵坐标

        2、确定动态规划的递推公式(状态转移方程)

                dp[i][j] = dp[i-1][j]+dp[i][j-1]

        3、确定动态规划的初始化条件

                可以通过图分析可知,在第一行第一列,都是一种路径

        4、确定动态规划的方向:

                从左向右,从上到下

        5、举例论证

                简单无需举例

整体代码:

class Solution {
public:int uniquePaths(int m, int n) {/*1、确定动态规划的dp数组含义以及下标含义dp[i][j]的含义是到达当前位置有多少条路径i是横坐标,j是纵坐标2、确定动态规划的递推公式(状态转移方程)dp[i][j] = dp[i-1][j]+dp[i][j-1]3、确定动态规划的初始化条件可以通过图分析可知,在第一行第一列,都是一种路径4、确定动态规划的方向左向右,从上到下5、举例论证简单无需举例*/vector<vector<int>>dp(m,vector<int>(n,0));//遍历dpfor(int i=0;i<m;i++){for(int j=0;j<n;j++){if(i==0||j==0){dp[i][j]=1;}else{dp[i][j] = dp[i-1][j] +dp[i][j-1];}}}return dp[m-1][n-1];}
};

不同路径Ⅱ

题目链接:63. 不同路径 II - 力扣(LeetCode)

代码随想录

整体思路:

        与上一个题类似,需要注意有障碍物

        1、障碍物在开始或者终点-->直接返回0

        2、障碍物在第一行、第一列,障碍物之后的位置(包含障碍物坐标)路径全部为0

        3、障碍物在中间的网格,该点的路径为0

        (没进行代码优化,但是结果正确)

整体代码:

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {vector<vector<int>>dp(obstacleGrid.size(),vector<int>(obstacleGrid[0].size(),0));//定义dp数组//初始化//1、注意障碍物在起点、终点的情况if(obstacleGrid[0][0]==1||obstacleGrid[obstacleGrid.size()-1][obstacleGrid[0].size()-1]==1)return 0;//注意第一行、第一列正常应该是一条路径,但是如果出现了障碍,后边的网格的路径为0for(int i=0;i<obstacleGrid.size();i++)//遍历行,所以是第一列{if(obstacleGrid[i][0]==0){dp[i][0] =1;}else if(obstacleGrid[i][0]==1)break;}for(int j=0;j<obstacleGrid[0].size();j++){if(obstacleGrid[0][j]==0){dp[0][j]=1;}else if(obstacleGrid[0][j]==1){break;}}//遍历整个网格,从第二行第二列开始就行,因为第一行第一列初始化了for(int i=1;i<obstacleGrid.size();i++){for(int j=1;j<obstacleGrid[0].size();j++){if(obstacleGrid[i][j]==0)//说明不是障碍物{dp[i][j] = dp[i-1][j]+dp[i][j-1];}else if(obstacleGrid[i][j]==0)//可不写{dp[i][j] = 0;}}}return dp[obstacleGrid.size()-1][obstacleGrid[0].size()-1];//0,1}
};

整数拆分

题目链接:343. 整数拆分 - 力扣(LeetCode)

代码随想录

整体思路:

        目标:拆分的整数的乘积最大化

        dp数组的作用是将当前的元素与之前的状态相联系,

从1遍历到n,相当于拆分,将当前的拆分值与剩余值进行相乘,

        n=10

        j=1,j*9;对于9还可以继续拆,所以需要找到9的最大的拆分乘积进行记录

        j=2,j*8,对于8还可以继续拆,所以需要找到8的最大的查拆乘积分进行记录

。。。

        所以,对于一个数进行拆分,需要知道这个数之前的所有数的最大拆分,然后找到最大的值-->当前元素的值与之前元素的状态有关,可以使用动态规划dp

        (1)确定dp数组的含义、下标的含义

                dp数组表示当前数的最大拆分的乘积,下标表示当前元素

        (2)确定dp数组的迭代公式(状态转移方程)

                dp[i] = j*dp[i-j];dp[i-j]表示的是dp[i-j]的最大拆分乘积,之所以不需要对j进行拆分是因为j是遍历元素,所有的拆分项都在dp[i-j]中出现过

                同时要注意,dp[i]的获取还有一种情况,就是i-j本身就是最大值无需在进行拆分dp[i-j]

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

        (3)确定dp数组的初始化

                dp[0]=0,dp[1]=1,dp[2]=2;

        (4)确定dp数组的方向

                从小到n

        (5)举例论证

                无需举例

整体代码:

class Solution {
public:int integerBreak(int n) {//谨记dp数组表示当前元素的最大乘积,下标表示当前数组vector<int>dp(n+1,0);//注意要处理的是n而不是n-1dp[0]=0,dp[1]=1;for(int i=2;i<=n;i++)//遍历所有的dp数组{for(int j=1;j<i;j++)//通过遍历从0-i确定当前的最大dp[i]{//dp状态转移方程dp[i] = max(dp[i],max(j*dp[i-j],(i-j)*j));}}return dp[n];}
};

不同的二叉搜索树

题目链接:96. 不同的二叉搜索树 - 力扣(LeetCode)

代码随想录

整体思路:

整体代码:

http://www.dtcms.com/a/303696.html

相关文章:

  • PHP云原生架构:容器化、Kubernetes与Serverless实践
  • 【人工智能】OpenAI的AI代理革命:通向超拟人交互的未来之路
  • idea 服务器Debug端口启动设置
  • WD5018电压12V降5V,2A电流输出,应用于车载充电器车载设备供电
  • AI-调查研究-41-多模态大模型量化 Qwen2.5-VL:技术架构、能力评估与应用场景详解
  • TOPSIS(Technique for Order Preference by Similarity to Ideal Solution )简介与简单示例
  • Android Slices:让应用功能在系统级交互中触手可及
  • 从0到1理解大语言模型:读《大语言模型:从理论到实践(第2版)》笔记
  • Botanix 主网上线,开启 BTC 可编程新时代!
  • 【ASP.NET Core】探讨注入EF Core的DbContext在HTTP请求中的生命周期
  • Ruby 发送邮件 - SMTP
  • 广泛分布于内侧内嗅皮层全层的速度细胞(speed cells)对NLP中的深层语义分析的积极影响和启示
  • Angular面试题目和答案大全
  • SketchUp纹理贴图插件Architextures安装使用图文教程
  • 深入浅出设计模式——创建型模式之建造者模式
  • vue让elementUI和elementPlus标签内属性支持rem单位
  • nginx 413 Request Entity Too Large
  • uniapp 微信小程序 列表点击分享 不同的信息
  • 重塑浏览器!微软在Edge加入AI Agent,自动化搜索、预测、整合
  • 基于JavaWeb的兼职发布平台的设计与实现
  • Kubernetes 存储入门笔记:从 Volume 到 PVPVC 全解析
  • 【2025年7月29日】TrollStore巨魔商店恢复在线安装
  • 【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(5)——Tool Calling(工具调用)
  • Qt 与 OpenMP 并行编程结合
  • Spring Boot 3.5.x 使用 SpringDoc 2 / Swagger3
  • RTSP协议详解与C++实现实例
  • 01背包问题:Python动态规划深度解析与工程实践
  • 01 基于sklearn的机械学习-机械学习的分类、sklearn的安装、sklearn数据集、数据集的划分、特征工程中特征提取与无量纲化
  • TCP/IP
  • 详解 Python 实现线性回归模型:从理论到实践