Leetcoder Day36| 动态规划part03

343. 整数拆分

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

示例 1:

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

示例 2:

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

本题需要注意的是,至少拆成2个正整数的和,而不是正好是2个正整数。

  1. 确定dp数组以及下标的含义:dp[i]为整数i拆分后的最大乘积
  2. 确定递推公式:假如将i拆分为j和i-j,这里j不只是代表一个数字而是一可能由j个整数组成的乘积。如果从1遍历到j,有两种途径可以得到dp[i],一个是dp[i]=j*(i-j),另一个是dp[i]=j*dp[i-j],这里dp[i-j]代表i-j这个数字被拆分后的最大值。
  3. dp数组如何初始化:本题将i拆成0是没有意义的,所以不考虑,1拆开只能是1和0,也是没有意义的,所以从2开始初始化,2可以拆成1 + 1,因此dp[2]=1
  4. 确定遍历顺序:既然初始化是从2开始的,所以i从3开始遍历,j从1开始遍历,到i停止。
  5. 举例推导dp数组:没法通过简单计算举例。
class Solution {
    public int integerBreak(int n) {
        int[] dp=new int[n+1]; 
        dp[2]=1;
        for(int i=3;i<=n;i++){
            for(int j=1;j<i;j++){
                dp[i]=Math.max(dp[i], Math.max(j*dp[i-j], j*(i-j)));
            }
        }
        return dp[n];
    }
}

⚠️本题的优化思路:其实将对于j的遍历条件改为: j<i-1可以节省一步计算,因为如果让j=i-1,其实在 j = 1的时候,这一步就已经拆出来了,属于重复计算,所以 j < i - 1。

更优化一步,可以这样:

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

因为拆分一个数i使之乘积最大,比如i=x+(i-x) dp[i]=x(i-x)=xi-x^2,这时是一个向下的抛物线,最大点为x/2

96.不同的叉搜索树

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

示例:

这道题要求能构造多少二叉搜索树。二叉搜索树是有一定规律的,其中序遍历是有序的。按照示例所给,可以先从1开始遍历,看以i为根节点能构造出多少子树。其实一开始还是没有什么思路,主要是递推公式不太好想,所以准备按照五部曲依次思考一下:

  1. 确定dp数组以及下标的含义:dp[i]为有i个节点时能构造的二叉搜索树个数。
  2. 确定递推公式:目前还没有什么思路。
  3. dp数组如何初始化:若n=1,则dp[1]毫无疑问是1,若n=2,则有两种构造方法,一种是以1为根节点,左子树为空,右子树为2;一种是以2为根节点,左子树为1,右子树为空,所以dp[2]=2;n=3就是示例中所给情况,可以看到,如果以1为根节点,则左子树一定为空的,右子树有两种可能,分别是以2和3为子树根节点。若以2为根节点,则左右子树各有一个节点,有一种可能,若以3为根节点,则右子树为空,左子树有两种可能,分别是以1和2为子树根节点。

当分析到如何初始化的时候,已经渐渐有了关于推导递推公式的雏形,接下来可以捋一下思路:

当n=1时:只有一个节点,不附图了

当n=2时:如下

当n=3时,有三种大的情况:

  1. 以1为根节点:因为此题本质求的是树的形状的可能性,所以跟具体的数值关系不大,如果把1去掉来看,可以看到,其实剩下的形状和n=2的时候是一样的:
  2. 以2为根节点:左边节点1,右边节点3
  3. 以3为根节点:去掉3,剩下的形状和n=2的时候也是一样的:

因此

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

可以这样推导:

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

那么n=3时,dp[3]就是上面三种情况的搜索树个数之和,即dp[3]=dp[2]*dp[0]+dp[1]*dp[1]+dp[0]*dp[2] ,

拓展到i就是:不断地累加:dp[以j为头结点左子树节点数量]*dp[以j为头结点右子树节点数量],j的范围为[1, i]

所以递推公式为:dp[i]+=dp[j-1]*dp[i-j],因此下面完整的五部曲为:

  1. 确定dp数组以及下标的含义:有i个节点时能构造的二叉搜索树个数
  2. 确定递推公式:dp[i]+=dp[j-1]*dp[i-j]
  3. dp数组如何初始化:要注意,从定义上来讲,空节点也是一棵二叉树,也是一棵二叉搜索树,所以dp[0]=1,这个我一开始弄错了。dp[1]=1
  4. 确定遍历顺序:i从1到n,j从1到i
  5. 举例推导dp数组:无法手动举更多例子
class Solution {
    /**
    确定dp数组以及下标的含义:有i个节点时能构造的二叉搜索树个数
    确定递推公式:dp[i]+=dp[j-1]*dp[i-j]
    dp数组如何初始化:dp[1]=1,dp[2]=2
    确定遍历顺序:i从3到n,j从1到i
     */
    public int numTrees(int n) {
        int[] dp=new int[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.mfbz.cn/a/426607.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Excel 快速核对两列数据,找出不同

目录 一. 需求二. 条件格式&#xff0c;突出显示单元格规则 一. 需求 ⏹有如下图所示的两列&#xff0c;现在想根据C列的人名&#xff0c;找出B列中未出席的人名 二. 条件格式&#xff0c;突出显示单元格规则 先选中B3:B15&#xff0c;然后按住Ctrl键后&#xff0c;再接着选中…

游戏引擎分层简介

游戏引擎分层架构&#xff08;自上而下&#xff09; 工具层&#xff08;Tool Layer&#xff09; 在一个现代游戏引擎中&#xff0c;我们最先看到的可能不是复杂的代码&#xff0c;而是各种各样的编辑器&#xff0c;利用这些编辑器&#xff0c;我们可以制作设计关卡、角色、动画…

b站小土堆pytorch学习记录——P14 torchvision中的数据集使用

文章目录 一、前置知识如何查看torchvision的数据集 二、代码&#xff08;附注释&#xff09;及运行结果 一、前置知识 如何查看torchvision的数据集 &#xff08;1&#xff09;打开官网 https://pytorch.org/ pytorch官网 &#xff08;2&#xff09;打开torchvision 在Do…

设计模式:什么是设计模式?①

一、什么是设计模式&#xff1f; 1. 是一类程序设计思想 2. 是在大量实践过程中摸索总结出的标准经验提炼 3. 具有多样性和丰富性&#xff0c;不同情况应用的思想不同 二、设计模式的好处 1. 代码生产力和效率的提升 2. 让代码表现更为规整&#xff0c;简洁。阅读维护管理的成本…

机器学习-面经

经历了2023年的秋招&#xff0c;现在也已经入职半年了&#xff0c;空闲时间将面试中可能遇到的机器学习问题整理了一下&#xff0c;可能答案也会有错误的&#xff0c;希望大家能指出&#xff01;另外&#xff0c;不论是实习&#xff0c;还是校招&#xff0c;都祝福大家能够拿到…

黑科技工具盒源码 好用的手机工具盒iAPP源码

全新推出&#xff01;多功能工具箱&#xff1a;一款实用的手机工具集&#xff0c;提供丰富的免费小工具&#xff0c;操作简便。目前包含六项黑科技功能&#xff0c;分别为QQ云端、短信测压、Q绑查询、照妖镜、chatgpt、网页一键打包APP。工具箱体积小巧&#xff0c;不占内存&am…

网络编程:TCP机械臂,UDP文件传输

1.TCP机械臂测试 程序代码&#xff1a; 1 #include<myhead.h>2 #define SER_IP "192.168.126.112" //服务器IP3 #define SER_PORT 8888 //服务器端口号4 5 #define CLI_IP "192.168.126.121" //客户端IP6 #define CLI_PORT 9999 //…

Microsoft PyRIT能自动化完成AI红队的任务

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

web3时事粥报

比特币正成为更具有吸引力的通胀对冲工具 在通胀的宏观经济浪潮中&#xff0c;比特币正逐渐崭露头角&#xff0c;成为那些渴望多元化投资组合的投资者眼中的璀璨明星。Kooner 预测&#xff0c;2024年&#xff0c;各种宏观经济挑战可能进一步提升比特币、黄金和白银等资产的避险…

群体风暴之锤(War3地图编辑器)

文章目录 0、大致原理1、创建隐形单位2、新事件开端3、环境→新条件4、动作4.1、单位组4.1.1、圆范围内单位4.1.2、指定条件 4.2、对单位组内的所有单位释放风暴之锤 0、大致原理 真MK向目标点释放风暴之锤时选定&#xff08;以技能释放点为圆心&#xff0c;设定半径&#xff0…

【RT-DETR有效改进】结合SOTA思想利用双主干网络改进RT-DETR(全网独家创新,重磅更新)

一、本文介绍 本文给大家带来的改进机制是结合目前SOTAYOLOv9的思想利用双主干网络来改进RT-DETR&#xff08;本专栏目前发布以来改进最大的内容&#xff0c;同时本文内容为我个人一手整理全网独家首发 | 就连V9官方不支持的模型宽度和深度修改我都均已提供&#xff0c;本文内…

JUC并发编程 深入学习Java并发编程【上】

JUC并发编程&#xff0c;深入学习Java并发编程&#xff0c;与视频每一P对应&#xff0c;全系列6w字。 P1-5 为什么学特色预备知识 进程线程概念 进程&#xff1a; 一个程序被运行&#xff0c;从磁盘加载这个程序的代码到内存&#xff0c;就开起了一个进程。 进程可以视为程…

搜索旋转排序数组[中等]

优质博文IT-BLOG-CN 一、题目 整数数组nums按升序排列&#xff0c;数组中的值 互不相同 。 在传递给函数之前&#xff0c;nums在预先未知的某个下标k&#xff08;0 < k < nums.length&#xff09;上进行了 旋转&#xff0c;使数组变为[nums[k], nums[k1], ..., nums[n-…

C语言冒泡排序(高级版)

目录: 冒泡排序的原理 主函数 "冒泡排序函数" 比较函数 交换函数 最终输出 完整代码 冒泡排序的原理: 冒泡排序的原理是&#xff1a;从左到右&#xff0c;相邻元素进行比较。每次比较一轮&#xff0c;就会找到序列中最大的一个或最小的一个。这个数就会从序列的最右…

Qt 简约美观的加载动画 第九季

这次和大家分享6个非常清爽的加载动画. &#x1f60a; 效果如下 &#x1f60a; 一共三个文件 , 可以直接编译运行的呢 //main.cpp #include "LoadingAnimWidget.h" #include <QApplication> #include <QGridLayout> int main(int argc, char *argv[]) …

【机器人最短路径规划问题(栅格地图)】基于模拟退火算法求解

代码获取方式&#xff1a;QQ&#xff1a;491052175 或者 私聊博主获取 基于模拟退火算法求解机器人最短路径规划问题&#xff08;栅格地图&#xff09;的仿真结果 仿真结果&#xff1a; 初始解的路径规划图 收敛曲线&#xff1a; 模拟退火算法求解的路径规划图 结论&#xff…

DVWA靶场 Command Injection,高中低

Low 输入ip地址正常显示&#xff0c;尝试加入其他命令 127.0.0.1 & whoami 后面的whoami也执行了 Medium whoami也可以执行 好像&可应用&#xff0c;&&应该是被过滤 High &用不了&#xff0c;应该是过滤了吧 经过尝试&、|都无法用 查看源码后发现有…

GO逃逸分析

内存管理 内存管理主要包括两个动作&#xff1a;分配与释放。逃逸分析就是服务于内存分配的&#xff0c;而内存的释放由GC负责。 栈 在Go语言中&#xff0c;栈的内存是由编译器自动进行分配和释放的&#xff0c;栈区往往存储着函数参数、局部变量和调用函数帧&#xff0c;它…

Java 计算某年份二月的天数

一、实验任务 要求编写一个程序&#xff0c;从键盘输入年份&#xff0c;根据输入的年份计算这一年的2月有多少天。 二、实验内容 三、实验结果 四、实现逻辑和步骤 &#xff08;1&#xff09;使用scanner类实现程序使用键盘录入一个年份。 &#xff08;2&#xff09;使用if语…

百度诉闪速推公司涉“万词霸屏”不正当竞争纠纷案审理结果

交叉口讯 5月13日&#xff0c;江苏省高级人民法院知识产权庭公布百度诉闪推公司涉及“万磁霸屏”不正当竞争纠纷一案审理结果&#xff1a;判决闪推公司应立即停止涉案的不正当竞争行为。 &#xff0c;公司在其公司官网发布声明&#xff0c;消除影响&#xff0c;并赔偿百度经济损…