0/1背包问题-----动态规划求解

本文详细介绍了0/1背包问题,通过动态规划方法求解。首先阐述了问题描述和分析,接着分别展示了递归和迭代两种方式的解题过程。递归虽然直观但消耗栈空间,而迭代则减少了空间开销,两者都用于确定物品装入背包的最佳策略,以最大化价值。文章提供了完整的递归和迭代解法,并解释了如何根据解法输出装入情况。
摘要由CSDN通过智能技术生成

问题描述

有n个物品和一个容量为c的背包,从n个物品中选取装包的物品。物品i的重量为w[i],价值为p[i]。一个可行的背包装载是指,装包的物品总重量不超过背包的重量。一个最佳背包装载是指,物品总价值最高的可行的背包装载。
我们要求出x[i]的值。x[i] == 1表示物品i装入背包,x[i] == 0表示物品i没有装入背包。
问题的公式描述是:

//总价值最高的可能的背包装载,x[i]只能等于0或者1
max{p[1] * x[1] + p[2] * x[2] + ... + p[i] * x[i] + ... + p[n] * x[n]}

约束条件

//装入的所有物品的重量之和不大于背包容量
size_t totalWeight = 0;
for(size_t i = 1; i <= n; ++i)
{
    totalWeight += w[i] * x[i]; //x[i] = 0 || x[i] = 1
}
if(totalWeight <= c)
    //约束条件成立
else
    //约束条件不成立

问题分析

考察这样一个0/1背包问题: 总共4个物品,重量分别是w[1:4] = {8, 6, 2, 3},价值分别是p[1:4] = {8, 6, 4, 5},规定背包容量为12(即可以容纳的最大重量为12),求出获得最大价值的解情况。
如前所述,在该问题中,我们需要选择x[1],…,x[n]的值。假定我们按物品i = 1,2,…,n的顺序选择x[i]的值。如果选择x[1]=0,那么背包问题就转变为物品2,3,…,n,背包容量仍为c的问题。如果选择x[1]=1,那么背包问题就转变为物品2,3,…,n,背包容量为c-w[1]的问题。
所以在确定了物品i是否装入之后,背包问题就转变为i+1,i+2,…,n这些物品装入背包容量为c’或c’-w[i]的子问题(c’表示确定物品i是否装入之前背包所剩的容量)
又因为物品i装入与不装入是等可能的,在确定物品i的时候我们无法确定是装入它可以获得最优解还是不装入它可以获得最优解,所以需要分别计算这两种情况,然后取最优的一个。

假设f(i, y)表示容量为y,物品为i,i+1,…,n的背包问题的最优解的值,也就是说f(i, y)返回的值是物品从i到n,容量为y这个子背包可以获得的最大价值(最优解的值)。所以可以写出f的函数表达式:

//对于f(n, y)而言,即考虑最后一个物品是否装入时,
//如果剩余容量大于物品n的重量(即足够装入物品n),则返回的就是物品n的价值,
//否则,不装入物品n,返回的价值为0
if(y >= w[n])
    f(n, y) = p[n];
else //y >= 0 && y < w[n]
    f(n, y) = 0;
//对于f(i, y)而言,i >= 1 && i < n,即考察除最后一个物品之外的其他物品是否装入时,
//如果当前可用容量小于物品i的重量(即装不下物品i),则表示x[i] = 0,
//返回当前容量仍为y,物品从i+1到n的背包子问题的最优解
//如果当前可用容量大于等于物品i的重量(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值