动态规划从入坟走向入坑

目录

1.动态规划的含义

2.动态规划的解题步骤(动规五部曲)

3.动态规划的题型

 4.相关思路

1.动规基础(由于我看的博主讲的动规很简单,所以这里就不讲了)

2.背包问题

1.二维dp数组01背包

1.dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。

2.确定递推公式   最大值dp[i][j]

3.dp数组的初始化(这里就不给图了)

4. 确定遍历顺序

 5.举例推导dp数组打印dp数组看是否与题目答案一致

2.一维dp数组01背包(滚动数组)

1.dp[i] 表示容量为j的背包,价值总和最大是多少。

2.确定递推公式   最大值dp[i][j]

3.一维dp数组如何初始化

4. 确定遍历顺序

5.举例推导dp数组

文献引用


1.动态规划的含义

动态规划,英文:Dynamic Programming,简称DP(很多题解代码都是用的dp)(所以这里解释一下dp含义),如果某一问题有很多重叠子问题,使用动态规划是最有效的。

所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的.

2.动态规划的解题步骤(动规五部曲)

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

2.确定递推公式

3.确定dp数组的初始化

4.确定遍历顺序

5.举例推导dp数组打印dp数组看是否与题目答案一致

3.动态规划的题型

1.动规基础

2.背包问题

3.打家劫舍

4.股票问题

5.子序列问题

 4.相关思路

(今天先讲01背包哦),因为只学到这儿

1.动规基础(由于我看的博主讲的动规很简单,所以这里就不讲了)

2.背包问题

在下面的讲解中,我举一个例子:

背包最大重量为4。

物品为:

重量价值
物品0115
物品1320
物品2430

问背包能背的物品最大价值是多少? 

以下讲解和图示中出现的数字都是以这个例子为例。

weight[i] 表示背包各个物品的重量

value[i]  表示各个物品的价值

1.二维dp数组01背包

动规五部曲分析一波。

两个方向遍历 物品 和 背包容量

i
j重量价值
物品0
物品1
物品2

 二维嘛,必然有i和j变量

  ( 传统i 来表示物品、j表示背包容量。)

(如果想用j 表示物品,i 表示背包容量 行不行? 都可以的,个人习惯而已)

1.dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

要时刻记着这个dp数组的含义,下面的一些步骤都围绕这dp数组的含义进行的

也就是两种状态去或者不取,容量j背包背包背的最大价值

 如果还是不理解的话,那我举个搬家例子吧

那是一个晴朗的早晨,那天我需要搬东西回家,但是我需要坐高铁,东西带不了那么多,于是乎我只带了很多贵重的东西回家,我需要想的是带更多的有价值的东西,使其达到最大值

当然不必说寄快递,因为本身,它的价值就并不高,嘿嘿嘿嘿嘿嘿嘿嘿

这里应该解释的非常清楚了

2.确定递推公式   最大值dp[i][j]

前面乎3已经确定了含义,这里我们来到递推公式

重量价值
物品0115
物品1320
物品2430

这里我们来求两种情况,分别是放物品1 和 不放物品1,我们要取最大值(毕竟求的是最大价值

dp[1][3] = max(dp[0][3], dp[0][1] + 物品1 的价值)

放物品1 dp[i - 1][j]

不放物品1dp[i - 1][j - weight[i]] + value[i]

物品\背包容量背包容量0背包容量1背包容量2背包容量3背包容量4
物品0015151515
物品10151520
物品20
0
0

再在看其他情况。

状态转移方程 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化。

3.dp数组的初始化(这里就不给图了)

做如此高质量的文章,太费时间了,感觉我后面的不会如此久了,今天下午,就学习到了这,也可能是我码字的速度比较慢吧

首先从dp[i][j]的定义出发,如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。

在看其他情况。

状态转移方程 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化。

dp[0][j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。

那么很明显当 j < weight[0]的时候,dp[0][j] 应该是 0,因为背包容量比编号0的物品重量还小。

j >= weight[0]时,dp[0][j] 应该是value[0],因为背包容量放足够放编号0物品。

dp[0][j] 和 dp[i][0] 都已经初始化了,那么其他下标应该初始化多少呢?

其实从递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 可以看出dp[i][j] 是由左上方数值推导出来了,那么 其他下标初始为什么数值都可以,因为都会被覆盖。

初始-1,初始-2,初始100,都可以!

但只不过一开始就统一把dp数组统一初始为0,更方便一些。

4. 确定遍历顺序

 这里给出先遍历物品,然后遍历背包重量的代码

// weight数组的大小 就是物品个数
for (int i = 1; i < strlen(weight); i++) { // 遍历物品
    for (int j = 0; j <= strlen(beibao); j++) { // 遍历背包容量
        if (j < weight[i]) dp[i][j] = dp[i - 1][j];
        else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

    }
}

 先遍历背包,再遍历物品

// weight数组的大小 就是物品个数
for (int j = 0; j <= strlen(beibao); j++) { // 遍历背包容量
    for (int i = 1; i < strlen(weight)); i++) { // 遍历物品
        if (j < weight[i]) dp[i][j] = dp[i - 1][j];
        else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
    }
}

 5.举例推导dp数组打印dp数组看是否与题目答案一致

来看一下对应的dp数组的数值,如图:(左边是物品0物品1物品2)

引用哔哩哔哩代码随想录与上文一致

                                 背包重量       1                     2                  3                  4                     5

2.一维dp数组01背包(滚动数组)

这里我引用了哔哩哔哩博主代码随想录的,我觉得讲的很好!带你学透01背包问题(滚动数组篇) | 从此对背包问题不再迷茫!_哔哩哔哩_bilibili

1.dp[i] 表示容量为j的背包,价值总和最大是多少

2.确定递推公式   最大值dp[i][j]

接下来还是用如下这个例子来进行讲解一维dp数组01背包

背包最大重量为4。

物品为:

重量价值
物品0115
物品1320
物品2430

对于背包问题其实状态都是可以压缩的。

在使用二维数组的时候,递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

其实可以发现是dp[i][j]递推公式是由当前层和上一层复制dp[i - 1][j]还有放了i的最大价值dp[i - 1][j - weight[i]] + value[i])

因为是引用了上层数据,所以题目称为滚动.

这就是滚动数组的由来,需要满足的条件是上一层可以重复利用,直接拷贝到当前层。

读到这里估计大家都忘了 dp[i][j]里的i和j表达的是什么了,i是物品,j是背包容量。

dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

一维dp数组,其实就上一层 dp[i-1] 这一层 拷贝的 dp[i]来。

所以在 上面递推公式的基础上,去掉i这个维度就好。

递推公式为:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

3.一维dp数组如何初始化

关于初始化,一定要和dp数组的定义吻合,否则到递推公式的时候就会越来越乱

dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j],那么dp[0]就应该是0,因为背包容量为0所背的物品的最大价值就是0。

那么dp数组除了下标0的位置,初始为0,其他下标应该初始化多少呢?

看一下递归公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

dp数组在推导的时候一定是取价值最大的数,题目一般是正整数,所以这里我推荐直接初始化为0.

这样才能让dp数组在递归公式的过程中取的最大的价值,而不是被初始值覆盖了

那么我假设物品价值都是大于0的,所以dp数组初始化的时候,都初始为0就可以了。

4. 确定遍历顺序

代码如下:

for(int i = 0; i < strlen(weight); i++) { // 遍历物品
    for(int j = strlen(beibao); j >= weight[i]; j--) { // 遍历背包容量
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

    }
}

这里大家发现和二维dp的写法中,遍历背包的顺序是不一样的!但是其实还是要两层for循环

二维dp遍历的时候,背包容量是从小到大,而一维dp遍历的时候,背包是从大到小。

为什么呢?

我的理解是从后往前遍历,其实就是保证了背包dp[]的最大价值

因为二维省去了一维的i所以我们不知道是否前面带了物品i,可能会导致后面重复带物品i,所以我们从后面开始,从前面开始的话,就可以出现物美价廉的东西自己买多了,只能买一次,结果带了两次,没有考虑到前面的状态,已经买过了.

5.举例推导dp数组

引用哔哩哔哩代码随想录与上文一致

文献引用

代码随想录..代码随想录非常推荐,很值得学习的博主

代码还没有敲,就到了吃饭的点了,兄弟们,多点赞支持一下,赞就没有动力,谢谢个位大佬!! 
(后面修缮了一下,又肝了一个小时)

还望大佬一键三连 (如有误,请大佬指出,谢谢!!)

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

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

相关文章

Golang学习笔记_34——组合模式

Golang学习笔记_31——原型模式 Golang学习笔记_32——适配器模式 Golang学习笔记_33——桥接模式 文章目录 一、核心概念1. 定义2. 解决的问题3. 核心角色4. 类图 二、特点分析三、适用场景1. 文件系统2. 图形界面3. 组织架构 四、代码示例&#xff08;Go语言&#xff09;五、…

vue+elementplus创建初始化安装

项目创建初始化 D:\Tool\mysql\education_vue 这个路径下cmd 或打开vscode&#xff0c;把项目丢进code中打开 安装element plus Container 布局容器 | Element Plus npm install element-plus --save 把项目初始文件Homeview AboutView删了&#xff0c;Router index.js中删一…

SQL 优化工具使用之 explain 详解

一、导读 对于大部分开发人员来说&#xff0c;平常接触的无非就是增删改查这些基本操作&#xff0c;创建存储过程&#xff0c;视图等等都是 DBA 该干的活&#xff0c;但是想要把这些基本操作写的近乎完美也是一件难事。 而 explain 显示了 MySQL 如何使用索引来处理 select 语…

仿 Sora 之形,借物理模拟之技绘视频之彩

来自麻省理工学院、斯坦福大学、哥伦比亚大学以及康奈尔大学的研究人员携手开源了一款创新的3D交互视频模型——PhysDreamer&#xff08;以下简称“PD”&#xff09;。PD与OpenAI旗下的Sora相似&#xff0c;能够借助物理模拟技术来生成视频&#xff0c;这意味着PD所生成的视频蕴…

Python的顺序结构和循环结构

文章目录 一、条件语句&#xff08;1&#xff09;条件语句的定义&#xff08;2&#xff09;条件语句的语法&#xff08;a&#xff09;单分支 if&#xff08;b&#xff09;双分支 if-else&#xff08;c&#xff09;多分支 if-elif-elif-...-else &#xff08;3&#xff09;注意事…

04 redis数据类型

文章目录 redis数据类型string类型hash类型list类型set类型zset类型 &#xff08;sortedset&#xff09;通用命令 redis数据类型 官方命令&#xff1a;&#xff1a;http://www.redis.cn/commands.html Redis 中存储数据是通过 key-value 格式存储数据的&#xff0c;其中 val…

AutoGen:玩转多智能体团队协作 (Teams)

&#x1f449;&#x1f449;&#x1f449;本人承接各类AI相关应用开发项目(包括但不限于大模型微调、RAG、AI智能体、NLP、机器学习算法、运筹优化算法、数据分析EDA等) !!!&#x1f449;&#x1f449;&#x1f449; 有意愿请私信!!! AutoGen 的 AgentChat 模块为我们提供了强大…

Python PyCharm DeepSeek接入

Python PyCharm DeepSeek接入 创建API key 首先进入DeepSeek官网&#xff0c;https://www.deepseek.com/ 点击左侧“API Keys”&#xff0c;创建API key&#xff0c;输出名称为“AI” 点击“创建"&#xff0c;将API key保存&#xff0c;复制在其它地方。 在PyCharm中下…

分享8款AI生成PPT的工具!含测评

随着人工智能技术的飞速进步&#xff0c;制作PPT变得愈发便捷&#xff0c;仅需输入主题指令&#xff0c;便能在瞬间获得一份完整的演示文稿。尤其在制作篇幅较长的PPT时&#xff0c;手动编写每一页内容并设计格式和排版&#xff0c;不仅效率低下&#xff0c;而且耗时耗力。 本…

50页PDF|数字化转型成熟度模型与评估(附下载)

一、前言 这份报告依据GBT 43439-2023标准&#xff0c;详细介绍了数字化转型的成熟度模型和评估方法。报告将成熟度分为五个等级&#xff0c;从一级的基础转型意识&#xff0c;到五级的基于数据的生态价值构建与创新&#xff0c;涵盖了组织、技术、数据、资源、数字化运营等多…

aistdio部署deepseek-r1纯教程

前言 笔者电脑未扩容&#xff0c;想玩玩本地化的deepseek&#xff0c;苦于&#x1f447;久矣&#xff0c; 想到之前老师介绍的百度云平台飞桨AI Studio星河社区-人工智能学习与实训社区 于是就开始尝试部署终端版deepseek. 一、新建项目 1.打开飞桨网站&#xff0c;创建not…

实现动态翻转时钟效果的 HTML、CSS 和 JavaScript,附源码

实现动态翻转时钟效果的 HTML、CSS 和 JavaScript 在现代网页设计中&#xff0c;动画效果可以极大地增强用户体验。本文将介绍如何利用 HTML、CSS 和 JavaScript 创建一个动态翻转时钟的效果&#xff0c;模拟经典机械翻页时钟的视觉效果。我们将通过详细的步骤讲解如何实现时钟…

RagFlow+Ollama 构建RAG私有化知识库

RagFlowOllama 构建RAG私有化知识库 关于RAG一、什么是RAGFlow一、RAGFlow 安装配置测服已有服务&#xff1a; mysql、redis、elasticsearch 二、RAGFlow 配置 ollama&#xff1a;本地运行大型语言模型的工具软件。用户可以轻松下载、运行和管理各种开源 LLM。降低使用门槛&…

JavaScript(JS)

介绍 JavaScript(简称:JS)是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互 JavaScript 和Java 是完全不同的语言&#xff0c;不论是概念还是设计。但是基础语法类似 JS引入方式 内部脚本:将JS代码定义在HTML页面中 JavaScript代码…

LLM 架构

LLM 分类 : 自编码模型 (encoder) : 代表模型 : BERT自回归模型 (decoder) : 代表模型 : GPT序列到序列模型 (encoder-decoder) : 代表模型 : T5 自编码模型 (AutoEncoder model , AE) 代表模型 : BERT (Bidirectional Encoder Representation from Transformers)特点 : Enc…

剑指 Offer II 023. 两个链表的第一个重合节点

comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20023.%20%E4%B8%A4%E4%B8%AA%E9%93%BE%E8%A1%A8%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E9%87%8D%E5%90%88%E8%8A%82%E7%82%B9/README.md 剑指 Offer II 023. 两…

【git-hub项目:YOLOs-CPP】本地实现04:项目简化

项目跑通之后,我们常常还需要对我们没有用到的任何内容进行删除,以简化项目体积,也便于我们阅读和后续部署。如何实现呢?本篇博客教会大家实现! 项目一键下载【⬇️⬇️⬇️】: 精简后:【GitHub跑通项目:YOLOs-CPP】+【计算机视觉】+【YOLOv11模型】+【windows+Cpp+ONN…

R语言用逻辑回归贝叶斯层次对本垒打数据与心脏移植数据后验预测检验模拟推断及先验影响分析|附数据代码...

全文链接&#xff1a;https://tecdat.cn/?p40152 在统计学领域中&#xff0c;层次建模是一种极为强大且实用的工具。它能够巧妙地处理复杂的数据结构&#xff0c;通过分层的方式对数据进行建模。在贝叶斯统计的框架内&#xff0c;层次建模优势尽显&#xff0c;其可以有效地融合…

解锁机器学习核心算法 | 随机森林算法:机器学习的超强武器

一、引言 在机器学习的广阔领域中&#xff0c;算法的选择犹如为一场冒险挑选趁手的武器&#xff0c;至关重要。面对海量的数据和复杂的任务&#xff0c;合适的算法能够化繁为简&#xff0c;精准地挖掘出数据背后隐藏的模式与价值。机器学习领域有十大核心算法&#xff0c;而随…

网络工程师 (43)IP数据报

前言 IP数据报是互联网传输控制协议&#xff08;Internet Protocol&#xff0c;IP&#xff09;的数据报格式&#xff0c;由首部和数据两部分组成。 一、首部 IP数据报的首部是控制部分&#xff0c;包含了数据报传输和处理所需的各种信息。首部可以分为固定部分和可变部分。 固定…