Day 41 343.整数拆分 96.不同的二叉搜索树

整数拆分

给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

示例 1:

  • 输入: 2
  • 输出: 1
  • 解释: 2 = 1 + 1, 1 × 1 = 1。

示例 2:

  • 输入: 10
  • 输出: 36
  • 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
  • 说明: 你可以假设 n 不小于 2 且不大于 58。

​ 题解思路大致如下:

95BEC9AEC9CB8A1399C49FB3BBE4365C

​ 更加严格的证明如下(原题为1976年imo第四题):
1976IMO

​ 那么思路就明了了,对于n > 4的情况,尽可能的将数分解为3的和,递推公式即为dp[i] = dp[i - 3] *3;

​ 动态规划五部曲:

​ 1.确定dp数组及其下标含义:

​ 此处定义一维数组dp[i],下标i对应的是正整数的值,dp[i]则对应的是最大的正整数乘积;

​ 2.确定递推公式:

​ dp[i] = dp[i - 3]*3(i > 4)

​ 3.dp数组如何初始化:
​ dp[0] = 1, dp[1] = 1, dp[2] = 2, dp[3] = 4;即对应i <= 4的情况下的值,这样可以统一返回dp[i],不用做多次处理;

​ 4.dp数组应该如何遍历:

​ 本题很显然是从左到右顺序遍历;

​ 5.打印dp数组:

​ 1 1 2 4 6 9 12 18 27 36 54 81 108 162 ……

​ 代码实现如下:

#include<iostream>
#include<stdio.h>
#include<vector>
using namespace std;class Solution {
private:int integerBreak(int n) {vector<int> dp(n+1);//dp[0] = 1;//不用初始化,因为n >= 2if (n == 2)	return 1;else if (n == 3)	return 2;else if (n == 4)	return 4;else if (n == 5)	return 6;dp[1] = 1;dp[2] = 2;dp[3] = 4;dp[4] = 6;dp[5] = 9;for (int i = 6; i <= n; i++) {dp[i] = dp[i - 3] * 3;}return dp[n - 1];}
public:int test(int n) {return integerBreak(n);}
};
int main() {cout << "Please enter the target integer:(n >= 2)" << endl;int n;cin >> n;Solution mySolution;int res = mySolution.test(n);cout << "The Max product is:" << res << endl;cout << "the dp array will be shown as below:" << endl;for (int i = 2; i <= n; i++) {cout << mySolution.test(i) << " ";}cout << endl;return 0;
}

​ 很明显,这段代码是有很大的缺陷的,首先是初始化的过程太繁琐,理应有更简单的方法,其次由于初始化的时候已经初始化到了dp[5],所以一开始就需要n >= 4的时候才能正常运行,不然会报数组越界的错,最后就是这道题与其说是动态规划,更不如说是像贪心;

​ 重新考虑第二步递推公式:

​ 拆分整数有两种方法,即拆分成两数相乘和多数相乘:

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

​ 一个是j * dp[i - j],相当于是拆分(i - j);

​ 考虑简化:

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

不同的二叉搜索树

给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?

示例:

img

​ 先举例看看n = 1和n = 2时:

​ n = 3:

​ 当①为头节点时,其右子树的布局和n= 2的情况类似;

​ 当②为头节点时,其子树布局和n = 1时类似;

​ 当③为头节点时,其左子树布局也和n = 2时一致;

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

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

​ ③为头结点搜索树的数量 = 右子树有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];

​ 递推五部曲:

​ 1.确定dp数组以及下标的含义:

​ dp[i] :节点1到节点i组成的二叉搜索树的个数为dp[i];

​ 2.确定递推公式:

​ dp[i] += dp[j -1]*dp[i - j];

​ j-1 为j为头结点左子树节点数量,i-j 为以j为头结点右子树节点数量

​ 3.dp数组初始化:

​ 从定义上来讲,空节点也是一棵二叉树,也是一棵二叉搜索树;

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

​ 即dp[0] = 1;

​ 4.确定遍历顺序:

​ 由递归公式:dp[i] += dp[j -1]*dp[i - j];

​ 节点数为i的状态是依靠 i之前节点数的状态;

for (int i = 1; i <= n; i++) {for (int j = 1; j <= i; j++) {dp[i] += dp[j - 1] * dp[i - j];}
}

​ 5.举例dp数组:

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

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

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

相关文章

234234235

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

Python ArcPy批量将大量栅格文件的投影坐标系转为地理坐标系

本文介绍基于Python语言中的ArcPy模块&#xff0c;批量将多个遥感影像由投影坐标系转为地理坐标系的方法。 在之前的文章中&#xff0c;我们介绍过将单独1景遥感影像的投影坐标系转为地理坐标系的方法&#xff0c;大家可以参考文章投影坐标系转为地理坐标系&#xff1a;GDAL命令…

分布式与一致性协议之ZAB协议(四)

ZAB协议 ZooKeeper是如何选举领导者的。 首先我们来看看ZooKeeper是如何实现成员身份的&#xff1f; 在ZooKeeper中&#xff0c;成员状态是在QuorumPeer.java中实现的&#xff0c;为枚举型变量 public enum ServerState { LOOKING, FOLLOWING, LEADING, OBSERVING }其实&…

Windows系统本地部署Net2FTP文件管理网站并实现远程连接上传下载

文章目录 1.前言2. Net2FTP网站搭建2.1. Net2FTP下载和安装2.2. Net2FTP网页测试 3. cpolar内网穿透3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 文件传输可以说是互联网最主要的应用之一&#xff0c;特别是智能设备的大面积使用&#xff0c;无论是个人…

【MicroPython ESP32】ssd1306驱动0.96“I2C屏幕汉字显示示例

所需模块micropython-ssd1306模块 中文下载站&#xff1a;https://www.cnpython.com/pypi/micropython-ssd1306/download 官方下载站&#xff1a;https://pypi.org/project/micropython-ssd1306/ 汉字取模说明 取模工具&#xff1a;pctolcd2002取模方式&#xff1a; UTF-8字…

java 泛型题目讲解

泛型的知识点 泛型仅存在于编译时期&#xff0c;编译期间JAVA将会使用Object类型代替泛型类型&#xff0c;在运行时期不存在泛型&#xff1b;且所有泛型实例共享一个泛型类 public class Main{public static void main(String[] args){ArrayList<String> list1new Arra…

多表自动抄表系统

1.多表自动抄表系统的概述 多表自动抄表系统是一种先进的能源管理技术&#xff0c;主要用于电力、水、燃气等公用事业的计量数据采集。它通过自动化的方式替代了传统的人工抄表&#xff0c;提高了效率&#xff0c;降低了误差&#xff0c;同时为智能城市的数据分析提供了基础。…

2024-05-06 问AI: 介绍一下深度学习中的LSTM网络

文心一言 当谈到深度学习中的LSTM&#xff08;Long Short-Term Memory&#xff09;网络时&#xff0c;它是一种特殊的循环神经网络&#xff08;RNN&#xff09;架构&#xff0c;旨在解决传统RNN在处理长序列时遇到的梯度消失和梯度爆炸问题。LSTM网络因其能够捕捉序列数据中的…

每日两题 / 24. 两两交换链表中的节点 25. K 个一组翻转链表(LeetCode热题100)

24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 定义三个指针&#xff0c;交换前先保存ntnt指针为next->next&#xff0c;cur和next两个节点&#xff0c;然后将pre->next指向next 若pre为空&#xff0c;说明当前交换的节点为头两个节点&#xff0c;…

对XYctf的一些总结

对XYctf的一些总结 WEB 1.http请求头字段 此次比赛中出现的&#xff1a; X-Forwarded-For/Client-ip&#xff1a;修改来源ip via&#xff1a;修改代理服务器 还有一些常见的字段&#xff1a; GET&#xff1a;此方法用于请求指定的资源。GET请求应该安全且幂等&#xff0c…

【JavaEE网络】从数据链路层到应用层的DNS

目录 数据链路层以太网 DNS 数据链路层 越往下与程序员越远 代表协议&#xff1a;以太网。平常用的网线也叫“以太网线”&#xff0c;平常用的交换机也叫“以太网交换机” 以太网 认识以太网 “以太网” 不是一种具体的网络&#xff0c;而是一种技术标准&#xff1b;既包含…

电脑问题2【彻底删除CompatTelRunner】

彻底删除CompatTelRunner 电脑偶尔会运行CompatTelRunner造成CPU占用的资源非常大,所以这里要想办法彻底关闭他 本文摘录于&#xff1a;https://mwell.tech/archives/539只是做学习备份之用&#xff0c;绝无抄袭之意&#xff0c;有疑惑请联系本人&#xff01; 解决办法是进入W…