动态规划篇--代码随想录算法训练营第三十二天|343. 整数拆分,96.不同的二叉搜索树,01背包理论,01背包优化

news2024/11/15 7:05:33

 343. 整数拆分

题目链接:. - 力扣(LeetCode)

讲解视频:

动态规划,本题关键在于理解递推公式!| LeetCode:343. 整数拆分

题目描述:

给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积 。

示例 1:

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

解题思路:

1. 状态表示:

  • dp[i] 表示将整数 i 拆分成至少两个正整数的和之后,这些正整数乘积的最大值。

2. 状态转移方程:

 代码中使用了两层循环来计算 dp[i]。第一层循环从 i = 3 开始,表示我们从 3 开始计算每个 i 的最大乘积。第二层循环遍历 j 从 1 到 i-1,表示将 i 拆分成 ji-j 的和,然后我们有两种选择: 

  1. 不进一步拆分 i-j,直接计算 j * (i-j)
  2. 继续拆分 i-j,这时我们使用 j * dp[i-j]

对于每个 i,我们在 dp[i] 中取上述两种选择的最大值。 因此,状态转移方程为:dp[i]=max⁡(dp[i],max⁡(j×(i−j),j×dp[i−j])) 

3. 初始化:

初始化的时候,我们可以认为每个 dp[i] 都至少为 1,这是因为任何一个整数 i 的最小拆分乘积至少为 1。 

4. 填表顺序:

 使用从左往右的顺序填充 dp 表,这样可以确保在计算 dp[i] 时,dp[i-j] 已经计算过。

5. 返回值:

 最终返回 dp[n]

代码:

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

96.不同的二叉搜索树

题目链接:. - 力扣(LeetCode)

讲解视频:

动态规划找到子状态之间的关系很重要!| LeetCode:96.不同的二叉搜索树

题目描述:

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

示例 1:

输入:n = 3
输出:5

解题思路:

1. 状态表示:
根据「拆分出相同子问题」的方式,抽象出来一个状态表示:
当我们在求个数为 n 的 BST 的个数的时候,当确定一个根节点之后,左右子树的结点「个数」也确定了。此时左右子树就会变成相同的子问题,因此我们可以这样定义状态表示:
dp[i] 表示:当结点的数量为 i 个的时候,一共有多少颗 BST 。

2. 状态转移方程:
对于 dp[i] ,此时我们已经有 i 个结点了,为了方便叙述,我们将这 i 个结点排好序,并且编
上 1, 2, 3, 4, 5.....i 的编号。
那么,对于所有不同的 BST ,我们可以按照下面的划分规则,分成不同的 i 类:「按照不同的头结点来分类」。分类结果就是:

  1. 头结点为 1 号结点的所有 BST
  2. 头结点为 2 号结点的所有 BST
  3.  ......

如果我们能求出「每一类中的 BST 的数量」,将所有类的 BST 数量累加在一起,就是最后结果。接下来选择「头结点为 j 号」的结点,来分析这 i 类 BST 的通用求法。
如果选择「 j 号结点来作为头结点」,根据 BST 的定义:

  • j 号结点的「左子树」的结点编号应该在 [1, j - 1] 之间,一共有 j - 1 个结点。那么 j 号结点作为头结点的话,它的「左子树的种类」就有 dp[j - 1] 种(回顾一下我们 dp 数组的定义哈);
  • j 号结点的「右子树」的结点编号应该在 [j + 1, i] 之间,一共有 i - j 个结点。那么 j 号结点作为头结点的话,它的「右子树的种类」就有 dp[i - j] 种;

根据「排列组合」的原理可得: j 号结点作为头结点的 BST 的种类一共有 dp[j - 1] *dp[i - j] 种!因此,我们只要把「不同头结点的 BST 数量」累加在一起,就能得到 dp[i] 的值: dp[i]
+= dp[j - 1] * dp[i - j] ( 1 <= j <= i) 。「注意用的是 += ,并且 j 从 1 变化到 i 」。


3. 初始化:
我们注意到,每一个状态转移里面的 j - 1 和 i - j 都是小于 i 的,并且可能会用到前一
个的状态(当 i = 1,j = 1 的时候,要用到 dp[0] 的数据)。因此要先把第一个元素初始
化。当 i = 0 的时候,表示一颗空树,「空树也是一颗二叉搜索树」,因此 dp[0] = 1 。


4. 填表顺序:
根据「状态转移方程」,易得「从左往右」。


5. 返回值:
根据「状态表示」,我们要返回的是 dp[n] 的值。

代码:

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

01背包理论

题目链接:01背包理论

讲解视频:

带你学透0-1背包问题!

题目描述:

小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。他需要带一些研究材料,但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实验样本等等,它们各自占据不同的空间,并且具有不同的价值。 

小明的行李空间为 N,问小明应该如何抉择,才能携带最大价值的研究材料,每种研究材料只能选择一次,并且只有选与不选两种选择,不能进行切割。

解题思路:

1. 状态表示:
dp[i][j] 表示:从前 i 个物品中挑选,总体积「不超过」 j ,所有的选法中,能挑选出来
的最大价值。


2. 状态转移方程:
线性 dp 状态转移方程分析方式,一般都是根据「最后一步」的状况,来分情况讨论:

  1. 不选第 i 个物品:相当于就是去前 i - 1 个物品中挑选,并且总体积不超过 j 。此时 dp[i][j] = dp[i - 1][j] ;
  2. 选择第 i 个物品:那么我就只能去前 i - 1 个物品中,挑选总体积不超过 j - v[i]的物品。此时 dp[i][j] = dp[i - 1][j - v[i]] + w[i] 。但是这种状态不一定存在,因此需要特判一下。

综上,状态转移方程为: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] +w[i]) 。


3. 初始化:
我们多加一行,方便我们的初始化,此时仅需将第一行初始化为 0 即可。因为什么也不选,也能满足体积不小于 j 的情况,此时的价值为 0 。


4. 填表顺序:
根据「状态转移方程」,我们仅需「从上往下」填表即可。


5. 返回值:
根据「状态表示」,返回 dpn] 。

代码:

#include<iostream>
#include<vector>
using namespace std;
 
int main()
{
    int n, m; 
    cin >> m >> n;
    vector<int> space(m+1);
    vector<int> value(m+1);
    for(int i = 1; i <= m; i++) cin >> space[i];
    for(int i = 1; i <= m; i++) cin >> value[i];
    vector<vector<int>> dp(m+1,vector<int>(n+1));
    for(int i = 1; i <= m; i++)//物品
    {
        for(int j = 0; j <= n; j++)//背包容量
        {
            dp[i][j] = dp[i-1][j];
            if(j >= space[i])
                dp[i][j] = max(dp[i][j],dp[i-1][j-space[i]]+value[i]);
        }
    }
    cout << dp[m][n];
    return 0;
}

01背包优化

解题思路:

利用滚动数组来做空间上的优化:

  1. 利用「滚动数组」优化;
  2. 直接在「原始代码」上修改。

在01背包问题中,优化的结果为:

  1. 删掉所有的横坐标;
  2. 修改一下 j 的遍历顺序-->从右向左,因为防止上一层hai'wei'b数被改变

代码:

#include<iostream>
#include<vector>
using namespace std;

int main()
{
    int n, m; 
    cin >> m >> n;
    vector<int> space(m+1);
    vector<int> value(m+1);
    for(int i = 1; i <= m; i++) cin >> space[i];
    for(int i = 1; i <= m; i++) cin >> value[i];
    vector<int> dp(n+1);
    for(int i = 1; i <= m; i++)//物品
        for(int j = n; j >= space[i]; j--)//背包容量
            dp[j] = max(dp[j],dp[j-space[i]]+value[i]);
    cout << dp[n];
    return 0;
}

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

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

相关文章

c++47 二级指针

二级指针的输入和输出模型 指针的输入&#xff1a;主调函数分配内存 指针输出 &#xff1a;被调用函数分配内存 指针做输入第一种模型 #define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h>// 二级指针做输…

《计算机组成原理》(第3版)第8章 CPU的结构和功能 复习笔记

第8章 CPU的结构和功能 一、CPU的结构 &#xff08;一&#xff09;CPU的含义 CPU实质包括运算器和控制器两大部分。 对于冯诺依曼结构的计算机而言&#xff0c;一旦程序进入存储器后&#xff0c;就可由计算机自动完成取指令和执行指令的任务&#xff0c;控制器就是专用于完成…

Python爬虫图片:从入门到精通

在数字化时代&#xff0c;图片作为信息传递的重要媒介之一&#xff0c;其获取和处理变得越来越重要。Python作为一种功能强大且易于学习的编程语言&#xff0c;非常适合用来编写爬虫程序&#xff0c;帮助我们自动化地从互联网上获取图片资源。本文将从基础到高级&#xff0c;详…

CTF密码学小结

感觉没啥好总结的啊 基础的永远是RSA、流密码、哈希、对称密码、古典密码那一套&#xff08;密码学上过课都会&#xff09;&#xff0c;其他的就是数论的一些技巧 似乎格密码也很流行&#xff0c;以及一些奇奇怪怪的性质利用也很多 1、random设置种子后随机的性质&#xff1a…

【LiteX】【开发板】【BoChenK7】使用Python开发FPGA【Hello World、LED点灯、Memory测速、替换BIOS】

目录 开发板介绍下载仓库工程设计工程构建构建流程 工程测试Hello WorldLED点灯Memory测速替换BIOS 开发板信息 开发板介绍 手头目前只有一个购买的BoChenK7开发板&#xff0c;后续会用它来进行LiteX FPGA SoC的构建 测试可能会包括&#xff1a; LED&#xff1a;本篇文章 DDR …

【区块链+乡村振兴】“蜜链盟”乡村振兴基层治理数字化平台 | FISCO BCOS应用案例

在国家战略政策推动和新一代信息化发展应用的合力之下&#xff0c;数字乡村是互联网化、信息化和数字化在农业农村经 济社会发展中的表现。为进一步加强乡村基层治理&#xff0c;根据《中共海南省委农村工作领导小组办公室海南省农业农 村厅关于在我省乡村治理中推广运用积分制…

【Docker】Docker Volume(存储卷)

一、什么是存储卷 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着&#xff0c;当我们在容器中的这个目录下写入数据时&#xff0c;容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的目录。 在宿主…

xss-靶场

一、环境地址 XSS Game - Learning XSS Made Simple! | Created by PwnFunction 二、案例复现 案列1——Ma Spaghet&#xff01; <!-- Challenge --> <h2 id"spaghet"></h2> <script>spaghet.innerHTML (new URL(location).searchParams…

idea2022新建jsp项目并配置Tomcat服务器

1、创建项目 2、添加jdk 步骤如下&#xff0c;然后点击下边的create 创建项目即可 3、点击file 4、选择模块添加web 5、配置tomcat 6、依次点击 7、新建jsp文件 8、成功显示

Python 全栈系列262 使用sqlalchemy(clickhouse)

说明 再补充一篇。之前连不上的原因也挺搞笑&#xff0c;大概是deepseek把我带偏了&#xff0c; 应该是 pip3 install clickhouse-sqlalchemy -i https://mirrors.aliyun.com/pypi/simple/ 但是它教我 pip3 install sqlalchemy-clickhouse -i https://mirrors.aliyun.com/py…

Keepalived总结笔记

环境准备&#xff1a;两台安装ka的服务器&#xff0c;两台客户机&#xff0c;IP无要求&#xff0c;关闭火墙和selinux 1.在两台主机上安装ka 全局配置文件在/etc/keepalived/keepalived.conf 可以改写邮件地址和发送邮件的地址和主机唯一标识以及组播地址 配置虚拟路由&…

基于单片机的智能晾衣系统设计

摘 要 &#xff1a;在网络信息技术的推动下&#xff0c;智能家居得到了广泛应用&#xff0c;文章根据当前的市场动态&#xff0c;针对基于单片机的智能晾衣系统设计展开论述&#xff0c;具体包括两个方面的内容———硬件设计和软件设计。 关键词 &#xff1a;单片机&#xff…

经方药食两用服务平台

TOC springboot226经方药食两用服务平台 绪论 1.1研究背景与意义 信息化管理模式是将行业中的工作流程由人工服务&#xff0c;逐渐转换为使用计算机技术的信息化管理服务。这种管理模式发展迅速&#xff0c;使用起来非常简单容易&#xff0c;用户甚至不用掌握相关的专业知识…

【经典算法】BFS_最短路问题

1. 最短路问题介绍 最短路径问题是图论中的一类十分重要的问题。本篇文章只介绍边权为1(或边权相同)的最简单的最短路径问题。所谓边权&#xff0c;就是两点之间的距离。 这类问题通俗的说就是告诉你起点和终点&#xff0c;要你找出最短的路径或是最短路径是多少。 解决方法&…

每日OJ_牛客_DP3跳台阶扩展问题

目录 DP3跳台阶扩展问题 题解代码1&#xff08;dp&#xff09; 题解代码2&#xff08;找规律&#xff09; DP3跳台阶扩展问题 跳台阶扩展问题_牛客题霸_牛客网 题解代码1&#xff08;dp&#xff09; 假定第一次跳的是一阶&#xff0c;那么剩下的是n-1个台阶&#xff0c;跳法…

汇编语言:jcxz 指令

‌ 在汇编语言中&#xff0c;jcxz 标号 指令是一个有条件转移指令&#xff0c;用于检测CX寄存器的值&#xff0c;如果CX寄存器的值为0&#xff0c;则跳转到指令中标号所指定的地址处执行&#xff1b;否则&#xff0c;指令将继续顺序执行。‌ 1. jcxz 标号 &#xff0…

超市收银出入库进销存库存管理系统java数据库SpringBoot前端VUE

系统设计是一个把软件需求转换成用软件系统表示的过程[9]。通过对目标系统的分析和研究&#xff0c;做出了对师范学院实习管理系统的总体规划&#xff0c;这是全面开发系统的重要基础。在对实习管理系统全面分析调查的基础上&#xff0c;制定出商品销售系统的总体规划。系统设计…

KEEPALIVED的高可用实现

目录 一.高可用集群 1.1 集群类型 Keepalived 环境准备 1.2Keepalived 相关文件 1.3实验步骤 1.3.1HTTP配置 1.3.2安装KA 1.3.3实现master/slave的 Keepalived 单主架构 1.3.4抢占模式和非抢占模式 非抢占模式 抢占模式 抢占延迟模式 preempt_delay 1.3.5开启KA…

习题2.38-2.39

2.38这个题目特别有意思,能比较深的理解什么是左侧优先右侧优先。先看看实现代码 ;;满足交换律,即操作函数的参数可相互交换,其结果不变 (defn fold-right[op initial sequences](if (empty? sequences)initial(op (first sequences)(accumulate op initial (rest sequence…

快讯 | 28页知网侵权函难挡秘塔AI:多家数据库抢着合作!

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…