动态规划 (Dynamic Programming) 之 背包问题合辑 (Knapsack, Subset Sum, Partition and change making problem )

本文探讨了动态规划在解决01背包和完全背包问题的应用,包括问题描述、状态转移方程和C++实现。01背包允许每个物品最多放入一次,而完全背包则允许无限次。通过动态规划,可以找到在有限容量的背包中放置物品以最大化价值的最优解。
摘要由CSDN通过智能技术生成

背包问题一直是动态规划中的经典问题。这个问题又分成01背包,完全背包,多重背包,分组背包等等。。我在这里只记录下01背包(0-1knapsack)和完全背包(unbounded knapsack)。背包问题的简单描述就是有一个背包和一堆物品。每个物品有自己的大小和价值。我们希望在一个特定容量的背包中放入价值尽可能大的物品。01背包呢就是每个物品最多只能放一次,也就是要么放要么不放,所以被称为01背包。而完全背包呢就是每个物品可以放无限次。我们更喜欢unbounded knapsack这个名字。因为完全这次词其实没有表达清楚不限的意思。下面就是对完全背包和01背包就动态规划的方法做一些解析。

 

这两个问题中似乎01背包比较爽快,就从爽快的先说。类似的,我们还是要找到一个优化的子结构,然后递归式,然后代码。。

我们用M[i,j]来表示选用1...i件物品放入容量为j的背包时最大的价值。那样就吧这个情况分成2中情况分析。很简单。用这第i个物品,或者不用。如果不用那么M[i,j]就等于M[i-1,j](如果看不明白可以想象一下M的定义,这里M[i-1,j]的意义就是用1...i-1个物品来装容量为j的背包时的最优策略,也就是不用第i个物品了。) 。那如果用呢?那就是M[i-1, j - si ]+vi。(因为前面的策略已经满了j个容量,所以如果选用第i个物品,就要把总的容量j中减去第i个物品的容量,然后找到对应的M[i-1, j - si]加i的价值) 然后取一个大的值来决定选用那种策略。这个描述虽然有点拗口,但仔细琢磨意思还是直观的。所以这个表达式可以写成

M[i,j] = max { M[i-1,j], M[i-1,j-si]+vi }. 如果我们把他放在二维数组里面的话,可以看出来这里的M[i,j]取决与上一层的M[i-1]中的2个元素。

  • 3
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值