第四十一天 | 62.不同路径 63.不同路径|| 343.整数拆分 96.不同的二叉搜索树

题目:62.不同路径

1.二维dp数组dp[i][j]含义:到达(i,j)位置有dp[i][j]种方法。

2.动态转移方程:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]

3.初始化:dp[0][j] = 1, dp[i][0] = 1 (第一行第一列都为1)

4.遍历顺序:从上向下,从左往右

5.打印dp

二维数组怎么定义?

代码如下:

class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n, 0));for(int i = 0; i < m; i++){dp[i][0] = 1;}for(int j = 0; j < n; j++){dp[0][j] = 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 - 1][n - 1];}
};

题目:63.不同路径||

思路:

1.dp数组及含义:到达(i,j)位置有dp[i][j]种方法。

2.状态转移方程:dp[i][j] = dp[i - 1][j] + dp[i][j - 1](遇到空位置才进行计算)

3.初始化:dp[0][j] = 1, dp[i][0] = 1 (第一行第一列都为1)。当遇到障碍后停止。

4.遍历顺序:从上向下,从左往右

5.打印dp

代码如下:

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

题目:343.整数拆分

关键在于理解递推公式。(考虑好有几个需要比较的情况)

什么时候乘积最大?拆成尽可能相等的数

思路:

1.dp含义:数i经过拆分后,得到最大的乘积dp[i]

2.状态转移方程(dp[i] 是依靠 dp[i - j]的状态):

递推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

        1)有两种拆分方式:一是i * (i - j)直接相乘(把 i 拆成两个数);

                                    二是 j * dp[i - j](把 i 拆成三个数及以上)         

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

                因为在第二层循环中会不断得到新的dp[i],用本轮for循环得到的dp[i]与之前得到的最大的dp[i]作比较,取更大的。

3.初始化:

拆分0和拆分1的最大乘积是多少?

这是无解的。

这里我只初始化dp[2] = 1,从dp[i]的定义来说,拆分数字2,得到的最大乘积是1,这个没有任何异议!确定遍历顺序,先来看看递归公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

4.确定遍历顺序:从前到后

确定遍历顺序,先来看看递归公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

dp[i] 是依靠 dp[i - j]的状态,所以遍历i一定是从前向后遍历,先有dp[i - j]再有dp[i]。

5.打印dp数组:

class Solution {
public:int integerBreak(int n) {vector<int> dp(n + 1);dp[0] = 0;dp[1] = 0;dp[2] = 1;for(int i = 3; i <= n; i++){for(int j = 1; j <= i / 2; j++){dp[i] = max(max(j * (i - j), j * dp[i - j]), dp[i]);}}return dp[n];}
};

题目:96.不同的二叉搜索树

思路:

1.dp数组含义:含有 i 个节点的二叉搜索树共有dp[i]种

2.状态转移方程:

dp[3],就是 元素1为头结点搜索树的数量 + 元素2为头结点搜索树的数量 + 元素3为头结点搜索树的数量

元素1为头结点搜索树的数量 = 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量

元素2为头结点搜索树的数量 = 右子树有1个元素的搜索树数量 * 左子树有1个元素的搜索树数量

元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树数量

有2个元素的搜索树数量就是dp[2]。

有1个元素的搜索树数量就是dp[1]。

有0个元素的搜索树数量就是dp[0]。

所以dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2]

所以递推公式:dp[i] += dp[j - 1] * dp[i - j]; ,j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量

3.初始化:

初始化,只需要初始化dp[0]就可以了,推导的基础,都是dp[0]。

那么dp[0]应该是多少呢?

从定义上来讲,空节点也是一棵二叉树,也是一棵二叉搜索树,这是可以说得通的。

从递归公式上来讲,dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量] 中以j为头结点左子树节点数量为0,也需要dp[以j为头结点左子树节点数量] = 1, 否则乘法的结果就都变成0了。

4.遍历顺序:左往右

5.打印dp

容易犯得典型错误:

class Solution {
public:int numTrees(int n) {vector<int> dp(n + 1, 0);dp[0] = 1;      //易错:空二叉树也是二叉搜索树dp[1] = 1;dp[2] = 2;for(int i = 3; i <= n; i++){      //统计以1,2,...,n为结点有多少种不同的二叉树for(int j = 1; j <= i; j++){     //统计以1,2,...,i为头结点,同时共n个节点,有多少种不同的二叉树dp[i] += dp[j - 1] * dp[i - j]; }}return dp[n];}
};

在初始化时赋值dp[2]等于0,如果题目中n = 1,则会越界。

这一点很容易犯错

其实经常会有一个困惑,到底初始化时要初始前多少个呢?(手动模拟一下)

正确代码如下:

class Solution {
public:int integerBreak(int n) {vector<int> dp(n + 1);dp[0] = 0;for(int i = 1; i <= n; i++){for(int j = 1; j <= i / 2; j++){dp[i] = max(max(j * (i - j), j * dp[i - j]), dp[i]);}}return dp[n];}
};

其实只用定义dp[0] = 0,dp[1]往后都是可以动态规划循环推出来的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/14920.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp 安卓 Pc端真机浏览器调试

下载插件:真机模拟浏览器 1. 安装, 每次启用时使用usb 线连接电脑, 并且打开手机或者POS (调试设备)开发者模式, 比如我的是pos 机 则在系统设置中找到版本号,点击多次就会触发开发者模式 2.打开真机模拟软件,打开后会打开一个浏览器,如果想要模拟google的浏览器则 在浏览器地…

精准键位提示,键盘盲打轻松入门

在说明精准键位提示之前&#xff0c;我们先来看一张图&#xff1a; 这是一张标准的基准键位图&#xff0c;也就是打字时我们双手的8个手指放在基准键位上&#xff0c;在打不同的字母时&#xff0c;我们的手指以基准键位为中心&#xff0c;或上、或下、或左、或右&#xff0c;在…

《拯救大学生课设不挂科第二期之Windows11下安装VC6.0(VC++6.0)与跑通Hello,World!程序教程》【官方笔记】

背景与目标人群&#xff1a; 大学第一次学C语言的时候&#xff0c;大部分老师会选择VC6这个编辑器。 但由于很多人是新手&#xff0c;第一次上大学学C语言。 老师要求VC6.0&#xff08;VC6.0&#xff09;写C语言跑程序可能很多人还是第一次接触电脑。 需要安装VC6这个编辑器…

Docker常用软件安装

文章目录 1.安装Tomcat1.docker hub查找镜像并复制拉取镜像命令2.拉取镜像到本地1.执行官网命令2.查看是否拉取成功 3.启动tomcat4.退出和重启1.由于是以交互方式启动的&#xff0c;所以不方便&#xff0c;直接ctrl c退出2.查看当前的容器3.使用docker start 命令启动容器&…

【cocos creator 】生成六边形地图

想要生成一个六边形组成的地图 完整代码示例 以下是完整的代码示例&#xff0c;包含了注释来解释每一步&#xff1a; cc.Class({extends: cc.Component,properties: {hexPrefab: {default: null,type: cc.Prefab},mapWidth: 10, // 网格的宽度&#xff08;六边形的数量&am…

【Flutter】线性布局弹性布局层叠布局

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;Flutter学习 &#x1f320; 首发时间&#xff1a;2024年5月25日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43e; 目…

4、PHP的xml注入漏洞(xxe)

青少年ctf&#xff1a;PHP的XXE 1、打开网页是一个PHP版本页面 2、CTRLf搜索xml&#xff0c;发现2.8.0版本&#xff0c;含有xml漏洞 3、bp抓包 4、使用代码出发bug GET /simplexml_load_string.php HTTP/1.1 补充&#xff1a; <?xml version"1.0" encoding&quo…

内网穿透--Nps-自定义-上线

免责声明:本文仅做技术交流与学习... 目录 Nps项目: 一图通解: 1-下载nps/npc 2-服务端启动 访问web网页: 添加客户端&#xff0c;生成密匙. 3-kali客户端连接服务端 4-添加协议隧道. 5-kali生成后门&#xff1a; 6-kali创建监听: Nps项目: https://github.com/ehang…

蓝桥杯Web开发【模拟题一】15届

1.动态的Tab栏 日常在使用移动端 APP 或访问 PC 端网站的时候&#xff0c;常常发现在一些有工具栏或者 Tab 栏的页面会有顶栏固定的效果。简单来说&#xff0c;在页面未开始滚动时顶栏处在其原有的位置上&#xff0c;当页面向下滚动一定区域后&#xff0c;顶栏会跟随滚动固定在…

HTTPS证书——网站如何实现HTTPS访问?

实现网站HTTPS访问可以简化为以下四个基本步骤&#xff0c;确保过程既通俗易懂又条理清晰&#xff1a; 1. 申请SSL证书 - 目的&#xff1a;SSL证书是实现HTTPS加密的关键&#xff0c;它验证了网站的身份&#xff0c;并提供了加密数据所需的密钥。 - 操作&#xff1a;首先&…

TypeScript(持续更新中...)

1.TypeScript是什么&#xff1f; TypeScript是javaScript的超集。 2.使用TypeScript 1&#xff09;全局安装nodejs 2&#xff09;安装TypeScript编译器 npm i -g typescript 3.编译ts文件 //注意&#xff1a;需要在ts文件同级目录执行此命令&#xff0c;否则会报找不到…

遥感、GIS和GPS技术在水文、气象、灾害、生态、环境及卫生等领域中的应用

【科研必备】遥感、GIS和GPS技术在水文、气象、灾害、生态、环境及卫生等领域中的应用 (qq.com)https://mp.weixin.qq.com/s?__bizMzg2NDYxNjMyNA&mid2247565057&idx4&snecec1f5396132122acf02b188f7b74ac&chksmce6515eaf9129cfc9a6c4a16413c0d746003cc192132…

C++ Primer Plus第十七章复习题

1、iostream文件在CI/O中扮演这种角色&#xff1f; 答&#xff1a; iostream文件定义了用于管理输入和输出的类、常量和操纵符,这些对象管理用于处理I/O的流和缓冲区。该文件还创建了一些标准对象(cin、cout、cerr和 clog以及对应的宽字符对象)&#xff0c;用于处理与每个程序…

【论文笔记】| 微调LLM晶体生成

【论文笔记】| 微调LLM晶体生成 Fine-Tuned Language Models Generate Stable Inorganic Materials as Text NYU, ICLR 2024 Theme&#xff1a;Material Generation Main work&#xff1a; 微调大型语言模型以生成稳定的材料 可靠性&#xff1a;在样本结构中&#xff0c;90% …

如何修改WordPress网站的域名

我的网站用的是Hostease的虚拟主机&#xff0c;但是域名是之前在其他平台买的&#xff0c;而且已经快到期了&#xff0c;因为主机和域名在不同的平台上&#xff0c;管理不太方便&#xff0c;所以我又在Hostease重新注册了一个域名&#xff0c;然后把网站换成了新的域名&#xf…

(Java企业 / 公司项目)配置Linux网络-导入虚拟机

公司给了我一个IP地址 &#xff0c;提供了一个虚拟机或者自己搭建虚拟机&#xff0c;还有提供登录的账号密码 可以查看我之前的文章 VMware Workstation Pro 17虚拟机超级详细搭建&#xff08;含redis&#xff0c;nacos&#xff0c;docker, rabbitmq&#xff0c;sentinel&…

3D透视图模型转模型变形?---模大狮模型网

3D建模是数字艺术和设计领域中的重要技术&#xff0c;它可以为我们带来丰富多彩的视觉体验和创意表达。在本文中&#xff0c;我们将探讨一个引人注目的话题&#xff1a;3D透视图中模型转换是否会导致变形?通过深入探讨这个问题&#xff0c;我们希望能够帮助您更好地理解在3D建…

如何通过软件SPI读写W25Q64

STM32F1之SPI通信软件SPI代码编写-CSDN博客 目录 1. W25Qxx系列简介 2. W25Q64硬件电路 3. W25Q64框图 4. Flash操作注意事项 5. 代码编写 5.1 初始化 5.2 W25Q64读取ID号 5.3 W25Q64写使能 5.4 W25Q64等待忙 5.5 W25Q64页编程 5.6 W25Q64扇区擦除&#x…

WebRTC | 网络传输协议 RTP 和 RTCP

WebRTC | 网络传输协议 RTP 和 RTCP WebRTC | 网络传输协议 RTP 和 RTCP如何选择 TCP 与 UDPRTP概述工作机制报文结构RTP 的使用RTP 拓展头RTP 中的填充数据翻译器和混合器同步控制报文大小wireshark 抓取 RTP 报文 RTCP概述工作机制分组类型报文结构WebRTC 的反馈报文RTPFBPSF…

深入浅出递归算法

文章目录 递归思想递归的题目1.汉诺塔问题问题分析代码展示 2.合并两个有序链表问题分析代码展示 3.反转链表问题分析代码展示 4.两两交换 链表中的节点问题分析代码展示 总结 递归思想 递归就是将一个很大的问题拆分成子问题&#xff0c;然后再将子问题继续拆分&#xff0c;拆…