当前位置: 首页 > news >正文

[Python]代码随想录Day35[动态规划][背包问题]

01背包问题 二维

01背包:有n种物品, 每种物品只有一个

完全背包:有n种物品,每种物品有无限个

多重背包:有n种物品,每种物品的个数各不相同

eg:

背包的重量为4,装满这个背包的最大价值是什么?

暴力解法:

每个物品取或者不取  O(n^2) 回溯

有二维dp数组解法是基础,在这个基础上需要优化成一维dp数组

01背包解法:

1.dp数组的定义  含义

dp[i][j] 下标[0-1]之间的物品任取 然后放进容量为j的背包里  的价值

dp[i][j] 

不放物品i   的最大价值dp[i - 1][j]

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

不选:在剩余容量为c时,从前i- 1个物品中得到的最大价值和

选: 在剩余容量我c - weight(i)时,从前i - 1个物品中得到的最大价值之和

2.递推公式dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight(i)] + value(i))

3.初始化dp数组

4.遍历顺序

5.打印

n, bagweight = map(int, input().split())weight = list(map(int, input().split()))
value = list(map(int, input().split()))dp = [[0] * (bagweight + 1) for _ in range(n)]for j in range(weight[0], bagweight + 1):dp[0][j] = value[0]
# j 当前背包的重量
for i in range(1, n):for j in range(bagweight + 1):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])print(dp[n - 1][bagweight])

输入中map是用来转换数据类型的

map(int, ['1', '3', '4', '2'])
它的作用是把 int() 这个函数应用到列表中的每个元素,就像:
[int('1'), int('3'), int('4'), int('2')]  →  [1, 3, 4, 2]

input进来“1 3 5”

经过split变成["1","3","5"]  

再进过map变成map的object,

在经过list变成[1,3,5]

01背包问题 一维(滚动数组)

1.dp数组的定义  含义

dp[j]  容量为j的背包 所能装的最大价值为dp[j]

2.递推公式

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight(i)] + value(i))

dp[j] = max(dp[j], dp[j - weight[i]] + value[i])

 dp[j] 把上一层物品的数据拷贝下来了

3.初始化dp数组

dp[0] = 0

4. 遍历顺序 逆序遍历

n = 3, bagweight = 5
weight = [1, 3, 4]
value  = [15, 20, 30]
初始化
dp = [0, 0, 0, 0, 0, 0]   # 下标代表容量 0...5
处理物品 i=0(重1,价15)


外层 i=0;内层 j 从 5 → 1 递减:

j=5: dp[5] = max(dp[5], dp[4]+15) = max(0, 0+15)=15

j=4: dp[4] = max(dp[4], dp[3]+15) = 15

j=3: dp[3] = max(dp[3], dp[2]+15) = 15

j=2: dp[2] = max(dp[2], dp[1]+15) = 15

j=1: dp[1] = max(dp[1], dp[0]+15) = 15

结果:
dp = [0, 15, 15, 15, 15, 15]
处理物品 i=1(重3,价20
外层 i=1;内层 j 从 5 → 3:

j=5: dp[5] = max(dp[5], dp[2]+20) = max(15, 15+20)=35

j=4: dp[4] = max(dp[4], dp[1]+20) = max(15, 15+20)=35 → 但容量4装不下“1+3”同时吗?

装得下:1(重1)来自 dp[1]=15,再加当前物品(重3)共重4,值35 ✅

j=3: dp[3] = max(dp[3], dp[0]+20) = max(15, 0+20)=20

结果(处理完第2件后):
dp = [0, 15, 15, 20, 35, 35]
处理物品 i=2(重4,价30)
外层 i=2;内层 j 从 5 → 4:

j=5: dp[5] = max(dp[5], dp[1]+30) = max(35, 15+30)=45 → 选第0(重1,15) + 第2(重4,30) = 总重5,总值45

j=4: dp[4] = max(dp[4], dp[0]+30) = max(35, 0+30)=35 → 不变(容量4:放第2件价值30,其实比上一轮临时的35低,但上一轮的35来自“第0+第1”的组合,确实可行,所以保持35)

最终:
dp = [0, 15, 15, 20, 35, 45]
输出
print(dp[bagweight])  ->  dp[5] = 45

n, bagweight = map(int, input().split())
weight = list(map(int, input().split()))
value = list(map(int, input().split()))dp = [0] * (bagweight + 1)  # 创建一个动态规划数组dp,初始值为0dp[0] = 0  # 初始化dp[0] = 0,背包容量为0,价值最大为0for i in range(n):  # 应该先遍历物品,如果遍历背包容量放在上一层,那么每个dp[j]就只会放入一个物品for j in range(bagweight, weight[i]-1, -1):  # 倒序遍历背包容量是为了保证物品i只被放入一次dp[j] = max(dp[j], dp[j - weight[i]] + value[i])print(dp[bagweight])

416. 分割等和子集

哪些元素相加等于数组之和的一半

容量为11的背包能不能装满一个数组

1.dp含义

dp[j] 容量为j的背包,所背的最大价值为dp[j]

重点等于价值

target = nums.sum()/2

dp[target] = target

2.递推公式

dp[j] = max(dp[j], dp[j - weight[i] + value[i])

这里压缩是因为如果i表示物体索引,由于i从小到大遍历,那么本次dp[j]的值是由上次i-1得到的

dp[j] = max(dp[j],dp[j - nums[i]] + nums[i])

3.初始化

dp[0] = 0

4.遍历顺序

for i in len(len(nums)):

        for j in range(target, num[i] - 1, -1):

5.打印

class Solution:def canPartition(self, nums: List[int]) -> bool:if sum(nums) % 2 != 0:return Falsetarget = sum(nums) // 2dp = [0] * (target + 1)for num in nums:for j in range(target,num - 1, -1):dp[j] = max(dp[j], dp[j - num] + num)return dp[-1] == target

http://www.lryc.cn/news/614289.html

相关文章:

  • ELK+Redis+Nginx多节点部署实战:从日志收集到可视化分析
  • Docker容器部署discuz论坛与线上商城
  • Centos7升级redis
  • springboot读取编译时传递的参数
  • Spring AI 系列之四十 - Spring AI Alibaba-集成百炼智能体
  • 用browse实现菜单功能的方法
  • 《在 Spring Boot 中安全使用 Qwen API-KEY:环境变量替代明文配置的最佳实践》
  • 一文可视化分析2025年6月计算机视觉顶刊IJCV前沿热点
  • 数据结构(16)排序(上)
  • 代理模式在C++中的实现及面向对象设计原则的满足
  • vscode无法跳转到定义引用
  • 以下是使用这款ePub编辑器将指定章节转换为TXT文本文档的操作方法
  • JAVA基础-NIO
  • flutter TLS protocol versions: (TLSv1.2, TLSv1.3)
  • 【数据结构】排序(sort) -- 计数排序
  • 在 Elasticsearch/Kibana (ELK Stack) 中搜索包含竖线 (|)​​ 这类特殊字符的日志消息 (msg 字段) ​确实需要转义
  • 软件包管理、缓存、自定义 YUM 源
  • Vulnhub drippingblues 靶场复现 详细攻略
  • 强光干扰下误报率↓82%!陌讯多模态融合算法在高空抛物检测的实战优化
  • 自适应反步控制:理论与设计
  • 分布式微服务--GateWay的断言以及如何自定义一个断言
  • MySQL 配置性能优化赛:核心策略与实战技巧
  • 分布式系统性能优化实战:从瓶颈定位到架构升级
  • 前端后端之争?JavaScript和Java的特性与应用场景解析
  • Microsoft Dynamics AX 性能优化解决方案
  • 用JOIN替代子查询的查询性能优化
  • 深入解析基于Zookeeper分布式锁在高并发场景下的性能优化实践指南
  • DataFun联合开源AllData社区和开源Gravitino社区将在8月9日相聚数据治理峰会论坛
  • AI漫画翻译器-上传图片自动翻译,支持多语言
  • 分享超图提供的、很不错的WebGIS学习资源