0-1背包问题

问题描述
01背包问题可描述为如下问题:
有一个容量为V的背包,还有n个物体。现在忽略物体实际几何形状,我们认为只要背包的剩余容量大于等于物体体积,那就可以装进背包里。每个物体都有两个属性,即体积w和价值v。
问:如何向背包装物体才能使背包中物体的总价值最大?

问题描述
利用局部最优逐步推导去全局最优

当背包容量为6的时候不放西瓜时的最大价值为8
在这里插入图片描述
当放入西瓜后,背包还剩下容量2。后续只能在背包容量为2的情况下找到能装的最大值为6+3
在这里插入图片描述
在这里插入图片描述
伪代码

***
	dp[i][j]:编号为0-i之间的物品,任取放在容量为j的背包里
	
	递推表达式:不放物品i  data1 = dp[i-1][j]
				  放物品i  data2 = dp[i-1][j-weight[i]] + value[i];
				           dp[i][j] = max(data1,data2)

	初始化:第一列背包容量为0,直接初始化为0
			第一行:if(j >= weight[0]) dp[0][j] = value[0]

	遍历顺序:从左向右,从上到下
***
	
for i in range(1,物品+1):
	for j in range(1,容量+1):
		if(j < 物品i.weight:
			dp[i][j] = dp[i-1][j]
		else:
			data1 = dp[i-1][j] #不装入物品i
			data2 = dp[i-1][j-物品i.weight] + 物品i.value #装入物品i
			dp[i][j] = max(data1,data2)

解法2:使用滚动数组


使用一维滚动数组:每次计算完就讲上层的计算结果拷贝下来
	dp[j]:容量为j的背包所能装的最大价值

	递推公式:不放物品i data1 = dp[j]
			    放物品i data2 = dp[j-weight[i]] + value[i]
						dp[j] = max(data1,data2)	

	初始化:dp[i] = 0

	遍历顺序:for(i=0;i<物品数量;i++)  物品
				for(j=bagweight;j>=weight[i];j--)  背包
					递推公式

				为什么要倒序遍历背包:正序遍历会多次放同一个物品
				正序:dp[1] = dp[1-1] + 15 = 15
					  dp[2] = dp[2-1] + 15 = 30  可以看到第一个物品被放了两次

				倒序:dp[2] = dp[2-1] + 15 = 15
				 	  dp[1] = dp[1-1] + 15 = 15

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值