蓝桥杯专辑(Python组)——0-1背包问题

蓝桥杯专辑(Python组)——0-1背包问题

0-1背包问题简化

	有N件物品和⼀个最多能被重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能⽤⼀次,求解将哪些物品装⼊背包⾥物品价值总和最⼤。

示例

	假设背包的最大承重为max_weight,现有三个物品,分别是物品0,物品1,物品2,他们的重量分别是1,3,4,他们的价值分别是155,20,30。每件物品只能用一次,求解将哪些物品放入背包中物品的价值最大。

问题分析

物品价值重量
物品0151
物品1203
物品2304
#####   初始化参数 
####  物品数量
count = 3
####  背包最大 4
max_weight = 4
####  价值
value = [15,20,30]
####  重量
weight = [1,3,4]
	1.	确定dp数组维度。
	2.	初始化dp数组。

在step1中,确定dp数组,首先我们要明确dp数组中i,j的含义,dp[i][j]代表从前i中物品里任意选择,放进容量为j的背包里的最大价值。

	因此dp数组的维度应该是3×5的二维数组。
####构建dp数组
dp = [[0 for i in range(max_weight+1)] for j in range(count)]

在这里插入图片描述
在step2中,要初始化dp数组,在初始化dp时,对于上图可以发现,当j=0时,所有物品都不能放入,因此总价值为0,但是当j依次为1,2,3,4时,最大价值又不为零,因此在这个时候,物品0的重量小于j,因此最大价值是物品0的价值。

物品/背包容量01234
0015151515
10
20
	初始化dp数组的第一列与第一行 
####初始化dp数组的第一列与第一行 
for i in range(1):
    for j in range(max_weight+1):
        if weight[i] <= j:
            dp[i][j] = value[i]
	3.确定递推公式  
							dp[i][j] = dp[i-1][j]
							dp[i][j] = dp[i-1][j-weight[i]]+value[i]
由dp[i - 1][j]推出,即背包容量为j,⾥⾯不放物品i的最⼤价值,此时dp[i][j]就是dp[i - 1][j]
由dp[i-1][j-weight[i]]推出,dp[i-1][j-weight[i]]为背包容量为j-weight[i]的时候不放物品i的最⼤价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最⼤价值
	
		因此   dp[i][j] = max(dp[i-1][j-weight[i]]+value[i],dp[i-1][j])
		
	4. 判断条件  weight[i] 与 j 之间的大小 
物品/背包容量01234
0015151515
1015152035
2015152035

示意图

for i in range(1,count):
    for j in range(1,max_weight+1):
        if j >= weight[i]:
            dp[i][j] = max(dp[i-1][j-weight[i]]+value[i],dp[i-1][j])
        else:
            dp[i][j] = dp[i-1][j]

在这里从i=1,j=1开始遍历的原因是第一行,第一列我们已经初始化过。

全部代码

#####   初始化参数 
####  物品数量
count = 3
####  背包最大 4
max_weight = 4
####  价值
value = [15,20,30]
####  重量
weight = [1,3,4]

####构建dp数组
dp = [[0 for i in range(max_weight+1)] for j in range(count)]

####初始化dp数组的第一列与第一行 
for i in range(1):
    for j in range(max_weight+1):
        if weight[i] <= j:
            dp[i][j] = value[i]
####  递归
for i in range(1,count):
    for j in range(1,max_weight+1):
        if j >= weight[i]:
            dp[i][j] = max(dp[i-1][j-weight[i]]+value[i],dp[i-1][j])
        else:
            dp[i][j] = dp[i-1][j]

####  输出最后结果  
print(max(max(dp)))
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值