背包问题——01背包、完全背包、多重背包、分组背包(Python)

背包问题

背包问题是经典的动态规划 问题之一

这里只讨论01背包、完全背包问题,其余的暂不讨论


动态规划五部曲:

  • 确定dp数组(dp table)以及下标的含义
  • 确定递推公式
  • dp数组如何初始化
  • 确定遍历顺序
  • 举例推导dp数组

01背包

01背包指的是给定n个物品,每个物品有两个属性:

  • w[i]:第i个物品的重量(weight)
  • v[i]:第i个物品的价值(value)

再给一个背包容量W(能承受的最大总重量),问我们:

从这n个物品中选择若干个(每个物品最多只能选择一次 ),使得在不超过总容量W的前提下,获得的最大价值是多少?

力扣原题:
416. 分割等和子集
1049. 最后一块石头的重量 II
494. 目标和
474. 一和零


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

我们初始化了如下的dp数组,其中行代表背包的可用容量,列代表可用的物品。dp[i][j]代表容量为j的背包装入前i个物品的最大价值

物品\容量 0 1 2 3 4
0
1
2
3
4

2.dp数组初始化

对于容量为0的背包,面对所有的物品选择都只能不装入,因此所有的价值都是0,对于任意容量的背包,不选择物品的价值都是0

物品\容量 0 1 2 3 4
0 0 0 0 0 0
1 0
2 0
3 0
4 0

3.确定递推公式

在我们选择第i个物品时有两种选择方案:

1.不将当前物品装入背包

2.将当前物品装入背包

将当前第i物品装入背包时,我们的价值为:

1.不将物品装入背包,因此价值为相同容量下选择i-1个物品的价值,即dp[i][j] = dp[i-1][j]

2.将物品装入背包,因此价值为容量j-w[i]下的价值加上当前物品的价值,即dp[i][j] = dp[i-1][j - w[i]] + v[i]

综合来说,dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i]] + v[i])

4.确定遍历顺序

先按行遍历,再按列遍历,从1开始


滚动数组优化

完全背包

完全背包指的是给定n个物品,每个物品有两个属性:

  • w[i]:第i个物品的重量(weight)
  • v[i]:第i个物品的价值(value)

再给一个背包容量W(能承受的最大总重量),问我们:

从这n个物品中选择若干个(每个物品可以选择多次 ),使得在不超过总容量W的前提下,获得的最大价值是多少?

力扣原题:
518. 零钱兑换 II
377. 组合总和 Ⅳ
322. 零钱兑换
279. 完全平方数
139. 单词拆分

相关推荐
SuperEugene4 分钟前
Vue3 + Element Plus 中后台弹窗规范:开闭、传参、回调,告别弹窗地狱|Vue 组件与模板规范篇
开发语言·前端·javascript·vue.js·前端框架
SuperEugene6 分钟前
VXE-Table 4.x 实战规范:列配置 + 合并单元格 + 虚拟滚动,避坑卡顿 / 错乱 / 合并失效|表单与表格规范篇
开发语言·前端·javascript·vue.js·前端框架·vxetable
xushichao19897 分钟前
高性能密码学库
开发语言·c++·算法
偷懒下载原神7 分钟前
【linux操作系统】信号
linux·运维·服务器·开发语言·c++·git·后端
小涛不学习8 分钟前
Java面试全攻略(基础 + 集合 + 并发 + JVM + 框架)
java·开发语言
m0_518019489 分钟前
C++代码混淆与保护
开发语言·c++·算法
2301_818419019 分钟前
Python内存管理机制:垃圾回收与引用计数
jvm·数据库·python
m0_5698814711 分钟前
C++中的智能指针详解
开发语言·c++·算法
qq_4176950513 分钟前
构建一个桌面版的天气预报应用
jvm·数据库·python
cm65432014 分钟前
Python在金融科技(FinTech)中的应用
jvm·数据库·python