背包问题 python

一、01背包问题(经典)

问题描述:

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

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

输出描述:

35

思路:

思考第i件物品时,最大价值为max(不能取第i间物品的最大价值,能取第i件物品且剩余空间能装前i-1件物品的最大价值)

递推公式  
							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])
		
	

参考:蓝桥杯专辑(Python组)——0-1背包问题_蓝桥杯求解01背包问题python-CSDN博客

B站【DP动态规划】备战蓝桥杯——DP算法模板超详细讲解

具象化描述参考:

B站【自制】01背包问题算法动画讲解

两个B站视频之间的联系与区别:首先来说就是说思路是完全一样的,只是在dp数组行数代表的物品数时,讲解算法的物品从0,1,2开始,即物品0,物品1,物品2,但是在背包动画演示的视频中物品是从1开始计数,即物品1,物品2,物品3,所以在代码实现上有一些细微的区别。

具体代码:

使用二维数组进行求解

采取的是物品从0开始计数的方式
 

# coding = utf-8
# 初始化数量
count = 3
# 背包最大容量
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(dp[count - 1][max_weight])


#图形化参考网址:

二、完全背包问题

问题描述:

找零钱问题

使用一维数组进行解题

具体代码:

# coding = utf-8
def recDC(coinValueList, change, knownResults):
    '''
    找零问题
    :param coinValueList: 已有零钱的数值
    :param change: 需要找的零钱总数
    :param knownResults: 查询表--存储某个找零金额对应的最少硬币数
    :return: 最少硬币数
    '''
    minCoins = change
    if change in coinValueList:
        knownResults[change] = 1
        return 1
    #检查查询表中是否已经有某个找零金额对应的最少硬币数。如果没有,就递归地计算并且把得到的最少硬币数结果存在表中。
    elif knownResults[change] > 0:
        return knownResults[change]
    else:
        for i in [c for c in coinValueList if c <= change]:
            numCoins = 1 + recDC(coinValueList, change - i, knownResults)
            if numCoins < minCoins:
                minCoins = numCoins
                knownResults[change] = minCoins
    return minCoins


a =recDC([1, 5, 10, 25], 63, [0] * 100)
print(a)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值