算法学习打卡day40|343. 整数拆分、96.不同的二叉搜索树

343. 整数拆分

力扣题目链接
题目描述:
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
示例 1
输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。

思路:

  • 思路就是把整数拆分成两数之和,三数以上可以不用管,因为三数以上其实就是两数拆分的,我们就用两个数来做题,分别取第一个数和第一个数的dp之间的最大值,以及第二个数和第二个数dp之间的最值,然后相乘就是当前组的最大值,最后不断循环和dp[i]比较取最值即可。
  • 动态规划五部曲:
    1. 分析dp数组含义:dp[ i ]数组代表下标为i的整数拆分后元素乘积的的最大值
    2. 分析递推公式: dp[i] = max(dp[i], max(dp[i - j], i - j) * max(dp[j], j));
    3. dp数组初始化:因为我们拆分是从1开始拆分的那么下标0可以不用管,把下标1赋值为1,2也赋值为1,因为2只能拆分为1+1.
    4. 遍历顺序:显然是从前往后遍历,我们遍历的时候从下标i = 3开始,内层循环是去拆分i,比如3从1开始拆分为1和2,但是这里上界其实到 i / 2就可以了,多了就重复了。
    5. 推导数组结果:在这里插入图片描述

代码实现:

int integerBreak(int n) {/*dp[n] = max(dp[1]dp[n - 1],dp[2]dp[n - 2]..., dp[n / 2]dp[n - n / 2]);即:dp[i] = max(dp[i], max(dp[i - j], i - j) * max(dp[j], j));*/vector<int>dp(n + 1, 0);dp[1] = 1, dp[2] = 1;int left = 0, right = 0;for (int i = 3; i <= n; ++i) {for (int j = 1; j <= i / 2; ++j) {left = max(j, dp[j]);right = max(i - j, dp[i - j]);dp[i] = max(left * right, dp[i]);}}return dp[n];}
  • 这里left取最值那一步是可以省略的,为什么?
    • 因为代码实现方法是对j和i- j同时判断是否需要拆分,但是就算 j 它再怎么拆也是拆分成1 - i之间的某个元素再加上另外一个数或一组数(省去left取最值写法其实把这一个数或一组数包到dp[i - j]里了),所以,取到最值的时候,j 一定是1- i之间的某个值,然后dp序列是递增的,那么最值一定不在后 i / 2 里(随着基数增大),所以 j 的上界可以是 i / 2。
    • 数学证明如下(节选自力扣题解的某位同学回答):
      • 因为j * dp[i - j]包含了dp[j] * dp[i - j],这是可以证明的: 对j最优拆分:j = a1 + a2 +…+an; 对i - j 最优拆分:i - j = b1 + b2 +…+bn; 所以有 dp[j] = a1 * a2 … an; dp[i - j] = b1 * b2 *… bn; dp[i] * dp[i - j] = (a1 *a2 *…an) * (b1 * b2 … bn) = a1 * (a2 * … * an * b1 * b2 … bn) 令 k = a1,必有i - k = a2 + … + an + b1 + b2 +…+ bn(这就是对 i - k 的一种拆分) 也就是说如果以上这种对i - k的一种拆分是最优的,那么必有dp[j] * dp[i - j] = k * dp[i - k] 所以此时j * dp[i - j]包含dp[j] * dp[i - j]; 如果以上这种对i - k的拆分不是最优的,那这种拆分方案虽不会被j * dp[i - j]包含但也不会是答案;

96.不同的二叉搜索树

力扣题目链接
题目描述:
给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

示例 1:
在这里插入图片描述
输入:n = 3
输出:5

思路:

  • 我的思路是这样的,1到n的每个数字都可以作为根节点,那么外层for循环还是老套度去求dp数组,内层for循环去决定哪个数子作为根节点,然后将左右节点的dp值乘起来,然后不断加到dp[i]上。
  • 动态规划五部曲:
    1. 分析dp数组含义:dp[ i ]数组代表下标为i的整数的二叉树种类
    2. 分析递推公式: dp[n] = dp[n - 1] * dp[0] + dp[n - 2] * dp[1] + ... + dp[1]*dp[n - 2] + dp[0]* dp[n - 1]
    3. dp数组初始化:因为我们左子树可以是0个节点,而且我们要做乘法,所以下标0赋值为1,把下标1也赋值为1,遍历的时候下标从2开始
    4. 遍历顺序:显然是从前往后遍历,我们遍历的时候从下标 i = 2开始,那么外层for循环还是老套度去求dp数组,内层for循环去决定哪个数子作为根节点,然后将左右子树节点数的dp值乘起来,然后不断加到dp[i]上。
    5. 推导数组结果:1 1 2 5 14…

代码实现

int numTrees(int n) {if (n < 2) return 1;//dp[n] = dp[n - 1] * dp[0] + dp[n - 2] * dp[1] + ... + dp[1]*dp[n - 2] + dp[0]* dp[n - 1]vector<int> dp(n + 1);dp[0] = 1, dp[1] = 1;for (int i = 2; 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/156830.html

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

相关文章

基于深度学习网络的美食检测系统matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 % 图像大小 image_size [224 224 3]; num_classes size(VD,2)-1;% 目标类别数量…

vscode开启emmet语法

需要在setting.json中添加配置 首先进入设置&#xff0c;然后点击右上角 Vue项目添加如下配置 "emmet.syntaxProfiles": { "vue-html": "html", "vue": "html" },React项目添加如下配置 "emmet.includeLanguages&quo…

Docker(1)——安装Docker以及配置阿里云镜像加速

目录 一、简介 二、安装Docker 1. 访问Docker官网 2. 卸载旧版本Dokcer 3. 下载yum-utils&#xff08;yum工具包集合&#xff09; 4. 设置国内镜像仓库 5. 更新yum软件包索引 6. 安装Docker 7. 启动Docker 8. 卸载Docker 三、阿里云镜像加速 1. 访问阿里云官网 2. …

Qt 使用QtXlsx操作Excel表

1.环境搭建 QtXlsx是一个用于读写Microsoft Excel文件&#xff08;.xlsx&#xff09;的Qt库。它提供了一组简单易用的API&#xff0c;可以方便地处理电子表格数据。 Github下载&#xff1a;GitHub - dbzhang800/QtXlsxWriter: .xlsx file reader and writer for Qt5 官方文档…

云服务器 centos 部署 code-server 并配置 c/c++ 环境

将你的云服务器改为 centos 8 为什么要将云服务器的操作系统改成 centos 8 呢&#xff1f;原因就是 centos 7 里面的配置满足不了 code-server 的需求。如果你使用的是 centos 7 那么就需要你升级一些东西&#xff0c;这个过程比较麻烦。我在 centos 7 上面运行 code-server 的…

使用Nokogiri和OpenURI库进行HTTP爬虫

目录 一、Nokogiri库 二、OpenURI库 三、结合Nokogiri和OpenURI进行爬虫编程 四、高级爬虫编程 1、并发爬取 2、错误处理和异常处理 3、深度爬取 总结 在当今的数字化时代&#xff0c;网络爬虫已经成为收集和处理大量信息的重要工具。其中&#xff0c;Nokogiri和OpenUR…

我在Vscode学OpenCV 处理图像

既然我们是面向Python的OpenCV&#xff08;OpenCV for Python&#xff09;那我们就必须要熟悉Numpy这个库&#xff0c;尤其是其中的数组的库&#xff0c;Python是没有数组的&#xff0c;唯有借助他库才有所实现想要的目的。 # 老三样库--事先导入 import numpy as np import c…

入栏需看——管理类联考——英语——知识+记忆篇——导航页

文章目录 Section I Use of English——完型填空Section II Reading ComprehensionPart A——阅读理解 A 节&#xff08;Part A&#xff09;&#xff08;四篇&#xff09;Part B——阅读理解 B 节&#xff08;Part B&#xff09;&#xff08;只有一篇&#xff09;Part C——翻译…

堆栈与队列算法-以链表来实现队列

目录 堆栈与队列算法-以链表来实现队列 C代码 堆栈与队列算法-以链表来实现队列 队列除了能以数组的方式来实现外&#xff0c;也可以用链表来实现。在声明队列的类中&#xff0c;除了和队列相关的方法外&#xff0c;还必须有指向队列前端和队列末尾的指针&#xff0c;即fron…

webgl入门-基础三角形绘制

背景 最近工作上频繁接触webgl&#xff0c;因为不熟悉每每看到shader中的语法总感觉脑袋大&#xff0c;所以打算开始从零学习一下webgl&#xff0c;文章只做记录学习历程&#xff0c;那就直接开始吧&#xff01; 开始 可以配合着这个文章食用。 我还是对webgl有一些概念的&…

函数式接口详解(Java)

函数式接口详解&#xff08;Java&#xff09;_函数式接口作为参数_凯凯凯凯.的博客-CSDN博客 函数式接口&#xff1a;有且仅有一个抽象方法的接口 Java中函数式编程体现就是Lambda表达式&#xff0c;所以函数式接口就是可以适用于Lambda使用的接口 只有确保接口中仅有一个抽…

oracel处理XML时,报ORA-31011、ORA-19202。

原字段为clob&#xff0c; 查询 SELECT XMLTYPE(字段) FROM TABLE_A报错如下&#xff1a; ORA-31011: XML 语法分析失败 ORA-19202: XML 处理 LPX-00217: invalid character 12 (U000C) Error at line 1559时出错 ORA-06512: 在 "SYS.XMLTYPE", line 272 ORA-0651…