代码随想录|Day35|动态规划04|01背包(二维、一维)、416.分割等和子集

01背包(二维dp数组)

背包最大重量为4。

物品为:

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

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

动规五步曲:

  1. dp数组的含义:dp[i][j] 表示从下标为 [0 - i] 的物品里任取,放入容量为 j 的背包,价值总和最大是多少。(如下图所示)
  2. 递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])。对于每个物品,都有放于不放2种选择。如果不放第 i 件物品,dp[i][j] = dp[i - 1][j]。如果放第 i 件物品,dp[i][j] = dp[i - 1][j - weight[i]] + value[i](需要确保背包容量足够,否则 j - weight[i] 为负)
  3. 初始化:根据递推公式,dp[i][j] 由左上角推出,我们应该初始化第一行 dp[0][j] 和第一列 dp[i][0]dp[0][j] 容量小于 物品0重量的时候为0,大于等于 物品0重量的时候为物品0重量。dp[i][0] 表示背包容量为 0,无法放入任何物品,因此 dp[i][0] = 0
  4. 遍历顺序:先遍历物品还是先遍历背包都是可以的。
  5. 打印dp数组

 

 

def test_2_wei_bag_problem1():weight = [1, 3, 4]  # 物品的重量列表value = [15, 20, 30]  # 对应物品的价值列表bagweight = 4  # 背包的最大容量# 初始化动态规划表,行数为物品数量,列数为背包容量+1(从0到bagweight)# dp[i][j]表示在前i件物品中,对于容量为j的背包,可以获得的最大价值dp = [[0] * (bagweight + 1) for _ in range(len(weight))]# 初始化第一行,仅考虑第一件物品时的情况# 当背包容量大于等于第一件物品的重量时,可以选择放入这件物品for j in range(weight[0], bagweight + 1):dp[0][j] = value[0]# 逐个考虑剩下的物品for i in range(1, len(weight)):  # 遍历物品for j in range(bagweight + 1):  # 遍历背包容量# 如果当前背包容量小于物品i的重量,则物品i不能加入背包# 此时,最大价值与不考虑物品i时相同if j < weight[i]:dp[i][j] = dp[i - 1][j]# 否则,需要决定是加入物品i还是不加入# 加入物品i的情况下,最大价值为加入物品i之前的最大价值加上物品i的价值# 不加入物品i的情况下,最大价值与不考虑物品i时相同# 取两者的较大值else:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])# 输出最终结果:所有物品考虑完毕后,容量为bagweight的背包可以获得的最大价值print(dp[len(weight) - 1][bagweight])

01背包(一维dp数组)

 使用一维数组时,数组的每个元素dp[j]表示对于当前考虑的物品,容量为j的背包所能装入的最大价值。关键在于更新这个数组时需要从后往前更新,这样可以保证在更新dp[j]时,dp[j-weight[i]]仍然代表没有考虑当前物品时的状态。

动规五步曲:

  1. dp数组的含义:dp[j] 表示容量为 j 的背包,价值总和最大是多少。
  2. 递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
  3. 初始化:dp[0] = 0,因为背包容量为0所背的物品的最大价值就是0。其他下标应该初始化多少呢?看一下递归公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); dp数组在推导的时候一定是取价值最大的数,如果题目给的价值都是正整数那么非0下标都初始化为0就可以了。这样才能让dp数组在递归公式的过程中取的最大的价值,而不是被初始值覆盖了
  4. 遍历顺序:倒序遍历,01背包问题由于每个物品只有一个,正序遍历会导致同一个物品被多次加入背包。
  5. 打印dp数组

 

def test_2_wei_bag_problem1_optimized():weight = [1, 3, 4]value = [15, 20, 30]bagweight = 4# 初始化一维数组dp = [0] * (bagweight + 1)# 遍历物品for i in range(len(weight)):# 从后往前遍历背包容量# 注意这里的范围是 weight[i] 到 bagweight# 这是因为当背包容量小于物品重量时,该物品无法被选中for j in range(bagweight, weight[i]-1, -1):# 更新dp[j]dp[j] = max(dp[j], dp[j - weight[i]] + value[i])print(dp[bagweight])

416.分割等和子集

动规五步曲:

  1. dp数组的含义:dp[j] 表示容量为 j 的背包,价值总和最大是多少。
  2. 递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]), 物品i的重量和价值都是nums[i]
  3. 初始化:dp[0] = 0,从dp[j]的定义来看,首先dp[0]一定是0。如果题目给的价值都是正整数那么非0下标都初始化为0就可以了,如果题目给的价值有负数,那么非0下标就要初始化为负无穷。这样才能让dp数组在递推的过程中取得最大的价值,而不是被初始值覆盖了本题题目中 只包含正整数的非空数组,所以非0下标的元素初始化为0就可以了。
  4. 遍历顺序:倒序遍历,01背包问题由于每个物品只有一个,正序遍历会导致同一个物品被多次加入背包。
  5. 打印dp数组
class Solution:def canPartition(self, nums: List[int]) -> bool:# 如果数组的总和是奇数,直接返回False,因为无法分割成两个和相等的子集if sum(nums) % 2 != 0:return False# 计算目标和,即分割后每个子集应该达到的和target = sum(nums) // 2# 初始化动态规划数组,dp[j]存储的是能够通过选择数组nums中的若干个数,其总和最多能达到j的值dp = [0] * (target + 1)# 遍历每一个数字,尝试更新dp数组for num in nums:# 从后向前遍历,确保每个数字只被计算一次# 这里遍历到num是因为,当背包容量小于当前数字重量时,无法选择当前数字for j in range(target, num - 1, -1):# 更新dp[j],dp[j]是当前容量为j时能达到的最大和# 选择当前数字和不选择当前数字的最大值dp[j] = max(dp[j], dp[j - num] + num)# 如果dp数组的最后一个元素(即dp[target])等于目标和,说明可以分割成两个和相等的子集return dp[-1] == target
class Solution:def canPartition(self, nums: List[int]) -> bool:# 回溯(超时)total_sum = sum(nums)# 如果总和是奇数,则无法分割成两个和相等的子集if total_sum % 2 != 0:return Falsetarget = total_sum // 2def dfs(index, current_sum):# 如果当前子集的总和等于目标和,则找到了一个解if current_sum == target:return True# 如果当前和大于目标和或遍历完所有元素,则此路径不可行if current_sum > target or index == len(nums):return False# 尝试两种情况:将当前元素加入子集或不加入return dfs(index + 1, current_sum + nums[index]) or dfs(index + 1, current_sum)# 从第一个元素开始,当前子集总和为0return dfs(0, 0)

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

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

相关文章

17-1-HTML5 新增语义标签及属性

文章目录 HTML5 新增语义标签及属性1 HTML5 新增的块级语义化标签2 HTML5 新增的多媒体标签&#xff08;了解&#xff09;2.1 音频 audio2.2 视频 video 3 HTML5 新增的 input 类型&#xff08;了解&#xff09; HTML5 新增语义标签及属性 1 HTML5 新增的块级语义化标签 以前…

全新4.0版本圈子社交论坛系统 ,可打包小程序,于TP6+uni-app 全开源 可打包小程序app uniapp前端+全开源+独立版

简述 首先 圈子系统的核心是基于共同的兴趣或爱好将用户聚集在一起&#xff0c;这种设计使得用户能够迅速找到与自己有共同话题和兴趣的人。 其次 圈子系统提供了丰富的社交功能&#xff0c;如发帖、建圈子、发活动等&#xff0c;并且支持小程序授权登录、H5和APP等多种形式…

AI日报:北大Open Sora视频生成更强了;文心一言可以定制你自己的声音;天工 SkyMusic即将免费开放;

&#x1f916;&#x1f4f1;&#x1f4bc;AI应用 北大Open Sora视频生成更强了!时长可达10秒&#xff0c;分辨率更高 【AiBase提要:】 ⭐️ Open-Sora-Plan v1.0.0模型发布 显著提升视频生成质量和文本控制能力 ⭐️ 支持华为昇腾910b芯片&#xff0c;提升运行效率和质量。 ⭐…

STM32_IIC_AT24C02_3_读写操作

从图中可以看到&#xff0c;如果进行一个写的操作&#xff0c;也是要先发送一个启动操作&#xff0c;然后发送设备地址&#xff0c;接着发送字节地址&#xff0c;最后发送数据&#xff0c;然后停止。Tips:先发送高位&#xff0c;再发送低位 设备地址&#xff08;Device Address…

7款公司电脑监控软件

7款公司电脑监控软件 研究证明&#xff0c;人们在家办公的效率比在办公室办公的效率低一半&#xff0c;其中原因是缺少监督&#xff0c;即便在公司办公&#xff0c;还存在员工偷闲的时刻&#xff0c;比如聊天、浏览无关网站、看剧、炒股等&#xff0c;企业想提高员工的工作效率…

Azure的VFP和虚拟IP地址

Azure 的Virtual filtering platform (VFP) 是Azure 网络地址转换,端口转换和端口分配的基础。 下面我们来深入介绍一下VFP的工作方式。 VFP的出站动作。 对于客户端地址作为虚拟IP的出站目的地址的时候,VFP 驱动会负责做以下两个动作。 源地址转换。端口地址转换。VFP 和 S…

CSS 基础:设置背景的 5 个属性及简写 background 注意点

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。大专生&#xff0c;一枚程序媛&#xff0c;感谢关注。回复 “前端基础题”&#xff0c;可免费获得前端基础 100 题汇总&#xff0c;回复 “前端工具”&#xff0c;可获取 Web 开发工具合集 263篇…

Node.js创建第一个web服务

如果用PHP来编写后端代码&#xff0c;需要用Apache或者Nginx的服务器,来处理客户的请求响应。对于Node.js时&#xff0c;不仅实现了应用&#xff0c;同时还实现了整个HTTP服务器. 安装 Node Snippets插件&#xff08;编程自带提示&#xff09; console.log(你好nodejs); //表…

leetcode(HOT100)——链表篇

1、相交链表 本题思路就是定义两指针&#xff0c;指向两链表的同一起跑线&#xff0c;然后共同往前走&#xff0c;边走边判断两链表的节点是否相等&#xff0c; 代码如下&#xff1a; /*** Definition for singly-linked list.* public class ListNode {* int val;* L…

uniapp 表单使用Uview校验 包括城市选择器

<view><!-- 注意&#xff0c;如果需要兼容微信小程序&#xff0c;最好通过setRules方法设置rules规则 --><u--form labelPosition"left" :model"model1" :rules"rules" ref"uForm" labelWidth"174"><u…

C#互联网区域医学检验中心云LIS系统源码

云LIS联通四级&#xff08;市、县、乡、村&#xff09;检验服务网构建互联网检验服务新体系落地检验资源区域共享建设。云LIS系统是一种基于云计算技术的区域实验室信息管理系统&#xff0c;它的主要功能是管理实验室中的各种信息数据&#xff0c;包括样品数据、检测结果、仪器…

RuleEngine规则引擎底层改造AviatorScript 之公式规则

前情提要&#xff0c;看上一个文章&#xff0c;具体要实现的效果就是 当然上来的问题就是前端的问题&#xff0c;这个框首先他们用的是富文本&#xff0c;富文本传到后台的结果是前端脚本&#xff0c;带着h5的标签&#xff0c;后面改成了这个&#xff0c;当时这个东西其实和后…

自然语言处理-词向量模型-Word2Vec

目录 一、前言 二、词向量 三、词向量的实际意义 四、模型的整体框架 五、构建输入数据 六、不同模型的对比 七、负采样方案 八、总结 一、前言 计算机只认识数值数字&#xff0c;那么怎么认识自然语言呢&#xff1f;&#xff1f;&#xff1f;答案就是将自然语言转换转…

GFS分布式 文件系统

一、GFS的概念 文件存储分为nfs、lvm、raid 对象存储分为GFS、CEPH、fastDFS&#xff08;分布式文件存储&#xff09;NAS OSS S3 switch OSS 属于阿里云 通过URL 链接 S3属于亚马逊通过URL链接 1.1 GFS简介 开源的分布式文件系统&#xff0c;由存储服务器、客户端…

《系统架构设计师教程(第2版)》第8章-系统质量属性与架构评估-03-ATAM方法架构评估实践(下)

文章目录 3. 测试阶段3.1 头脑风暴和优先场景&#xff08;第7步&#xff09;3.1.1 理论部分3.1.2 示例 3.2 分析架构方法&#xff08;第8步&#xff09;3.2.1 调查架构方法1&#xff09;安全性2&#xff09;性能 3.2.2 创建分析问题3.2.3 分析问题的答案胡佛架构银行体系结构 3…

git查看单独某一个文件的历史修改记录

git查看单独某一个文件的历史修改记录 git log -p 文件具体路径 注意&#xff0c;Windows下默认文件路径分隔符是 \&#xff0c;在git bash 里面需要改成 /。 git基于change代码修改与提交_git change-CSDN博客文章浏览阅读361次。git cherry-pick&#xff1a;复制多个提交comm…

使用Nodejs + express连接数据库mongodb

文章目录 先创建一个js文档安装 MongoDB 驱动程序&#xff1a;引入 MongoDB 模块&#xff1a;设置数据库连接&#xff1a;新建一个表试试执行数据库操作&#xff1a;关闭数据库连接&#xff1a; 前面需要准备的内容可看前面的文章&#xff1a; Express框架搭建项目 node.js 简单…

麻雀优化算法(Sparrow Search Algorithm)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 算法背景 麻雀算法&#xff08;Sparrow Search Algorithm, SSA&#xff09;是一种受自然界麻雀群体行为启发的优化算法。想象一下&#xff0c;一…

(表征学习论文阅读)A Simple Framework for Contrastive Learning of Visual Representations

Chen T, Kornblith S, Norouzi M, et al. A simple framework for contrastive learning of visual representations[C]//International conference on machine learning. PMLR, 2020: 1597-1607. 1. 前言 本文作者为了了解对比学习是如何学习到有效的表征&#xff0c;对本文所…

3. Django 初探路由

3. 初探路由 一个完整的路由包含: 路由地址, 视图函数(或者视图类), 可选变量和路由命名. 本章讲述Django的路由编写规则与使用方法, 内容分为: 路由定义规则, 命名空间与路由命名, 路由的使用方式.3.1 路由定义规则 路由称为URL (Uniform Resource Locator, 统一资源定位符)…