动态规划的经典问题————背包问题(一)

最近在学习DP,从背包问题入门,这里记录下一些学习心得:

01背包

01背包是最基础的背包问题,一个体积为V的背包,要装N个物品,每个物品有体积c,价值w两种属性, 要求装入物品总价值最大。

用i表示第i个物品,这个物品的体积为 ci ,价值为 wi ,j表示当前已装入背包的物品总体积, dp[i][j] 表示在装入第i个物品时,背包已装物品总体积为j时的物品总价值。

动态规划问题的分析关键在于分析递推的过程,问题必须满足一个状态可以从另一个状态中推导出来。这里的状态就是 dp[i][j] ,它完全可以由 dp[i1][jci] 决定,因为01背包中每个物品只有装入或者不装入两种情况,装入第i个物品的结果,仅由装入第i-1个物品的结果决定:要么装入i,要么不装入。状态转移方程为 dp[i][j]=maxdp[i1][jci]+wi,dp[i1][j]

这里考虑优化空间复杂度,i的变化完全可以用循环的变量表示,用一维数组是否能够实现原先的状态转移呢?答案是可以,状态转移方程为 dp[j]=maxdp[jci]+wi,dp[j]

这里发现,花括号中的 dp[jci] dp[j] 对应的是之前 dp[i1][jci] dp[i1][j] 的值,那么在转移方程中,即装入第i个物品的时候, dp[jci] dp[j] 必须是装入第i-1个物品时的结果。每次遍历都是在将当前值更新成装入第i个物品的结果,如果顺序遍历j,状态转移方程中,下标大的值受小的值影响,此时下标大的值可能受更新后的结果影响,这就违背了原意,所以我们倒序遍历,就可以用一维数组完成状态转移。

这里又分为刚好装满,以及不完全装满两种情况。

  1. 要求刚好装满
    初始化一维数组时,仅将 dp[0] 初始化为0,其余均初始化为负无穷
  2. 可以不完全装满
    将一维数组全部初始化为0

至于原因,很简单:我们知道 dp[V] 就代表了物品总体积刚好等于背包总体积的情况,但是如果一维数组全部初始化是0,意味着不管能不能恰好装满背包, dp[V] 都是有值的。如果只置 dp[0] 为0,其余为 ,那么只有恰好完全装满时, dp[V] 才有值,否则为

参考资料:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值