动态规划系列总结-背包问题

review: 动规问题解决步骤

step1: 分析题目属于哪类问题,确定dp数组含义
step2: 确定dp状态转移公式
step3: 确定dp数组初始化,尤其注意递推公式中的边界值.(初始化需要参考状态转移公式)
step4: 确定递推顺序

不管是01背包还是完全背包都会出现求背包在某容量下最大值问题/求填满背包的最少物品等最值问题 ; 或 求有多少种方法填满背包等排列或组合问题

最值问题

  • 最大值问题,初始化为最小值; 最小值问题,初始化为最大值;
  • 循环遍历时,比较不放物品和放物品的值那个更大,更新最大值.
// 最大值
dp = [0 for i in range(n)] // 初始化为最小值0
dp[j] = max(dp[j],dp[j-weigh[i]] + values[i]) // 状态转移方程
// 最小值
dp = [ float("INF") for i in range(n)] // 初始化为最大值INF
dp[j] = min( dp[j] , dp[j-weight[i]] + values[i])

最值公式内部比较大小的具体数值不一定是dp[j-weight[i]] + values[i],可以根据题义改成dp[j-weight[i]] + 1;

排列或组合问题

考量双层遍历顺序,先遍历物品还是先遍历背包? 背包容量从大到小遍历还是从小到大遍历?

组合问题
  • 不强调元素之间的顺序
  • 先遍历物品,再遍历背包
排列问题
  • 强调元素之间的顺序问题
  • 先遍历背包大小, 再遍历物品

不管求组和还是求排列,都是用累加公式,而不是最大值公式;
这里要和回溯问题进行区分,回溯问题需要知道排列或者组合的具体情况,动规只需要只有有几种组合即可.

0-1背包问题

物品只有放入背包和不放入背包两种状态,考量物品是否可以重复放入.

dp数组定义:

dp可以设置为二维,也可以压缩空间设置成一维

  • dp[i][j]的定义为前0-i个元素可以将容量为j的背包填满的XX值(XX值是什么具体含义针对题目来定义)
  • dp[j]的定义为容量为j的背包填满可以达到的XX值
状态转移方程:
for i in range(len(nums)):
	for j in range(bagweights,weight[i]-1,-1)

为了避免重复放入,背包重量的遍历顺序为从最大容量到最小容量遍历

完全背包问题

物品不限个数,可以多次放入背包;

dp数组定义:

同0-1背包

状态转移方程:
for i in range(len(nums)):
	for j in range(weight[i],bagweights+1)

可以重复放入,所以背包重量的遍历顺序为从最小容量到最大容量遍历

题目链接

有(完全背包/0-1背包) + (最值问题/排列/组合问题) 的组合

最值

416 分割等和子集 (0-1背包 )
1049 最后一块石头的重量II (0-1背包)
474 一和零 (0-1背包)
322 零钱兑换 (完全背包)
279 完全平方数 (完全背包)

组合问题

518 零钱兑换II(完全背包)
494 目标和(0-1背包)

排列问题

377 组合总数IV(完全背包)
70 爬楼梯

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值