6月7号和6月8号: 01背包问题变种(动态规划简直有毒)

01背包问题是最经典的动态规划问题,主要要多做才能找到动态规划的划分规则。

01背包问题:

给定 n 件物品,物品的重量为 w[i],物品的价值为 c[i]。现挑选物品放入背包中,假定背包能承受的最大重量为 V,问应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?

首先是最为朴素的二维DP理解:DP = [[0] * V for _ in range(m)] 即求DP[i][j] 当在前面 i个物品中挑选到 j重量的物品的时候的最大价值为多少

所以动态转移方程为 DP[I][J] = MAX(DP[i-1][j], c[i] + DP[i-1][j-w[i]])

动态规划+压缩空间

观察上面的代码,会发现,当更新dp[i][..]时,只与dp[i-1][..]有关,也就是说,我们没有必要使用O(n*W)的空间,而是只使用O(W)的空间即可。下面先给出代码,再结合图例进行说明。

以6月8号的题目为例

1049. 最后一块石头的重量 II

有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。

每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下,就返回 0。

这道题目要转化一下问题。 转化为在 重量限制为总量一半的背包里面装入尽可能重的石头,总量减去2*DP即为目标值。

或者按照背包问题理解一步一步推导:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值