0-1背包问题python实现

0-1背包问题 ACWings题目链接:https://www.acwing.com/problem/content/2/
在这里插入图片描述
不会的小伙伴可以看一下视频:https://www.bilibili.com/video/BV15B4y1P7X7/

Python实现

# N件物品,一个容量为V的背包
N,V = map(int,input().split())
weight = []
val = []
# 创建两个列表,分别装入第i个物品的体积wi和价值vi
for _ in range(N):
    wi,vi = map(int,input().split())
    weight.append(wi)
    val.append(vi)
# base case: dp[0][...] = dp[...][0]=0
dp = [[0]*(V+1) for _ in range(N+1)] # (N+1)*(V+1) 
# dp[i][w]代表对于前i个物品,当背包容量为w时,可以装的最大价值
for i in range(1,N+1):
    for w in range(1,V+1):
        """
        if w-weight[i-1]<0:
            dp[i][w] = dp[i-1][w]
        else:
            dp[i][w] = max(
                # 装入物品i(下标对应在wight和val中是i-1),剩余的容量是 w-weight[i-1],
                # 则dp[i-1][w-weight[i-1]]对应的意思是,前i-1个物品,当背包容量抛去物品i之后可以装的最大价值
                dp[i-1][w-weight[i-1]]+val[i-1], 
                # 不装入物品i,
                dp[i-1][w])
        """
        # 简化版本
        dp[i][w] = dp[i-1][w]
        if w-weight[i-1]>=0:
            dp[i][w] = max(dp[i][w], dp[i-1][w-weight[i-1]]+val[i-1])
print(dp[N][V])

在这里插入图片描述

完全背包问题:(与01背包的区别在于完全背包中每种物品可以无限使用)
ACWings题目链接:https://www.acwing.com/problem/content/3/
很好的题解:https://www.acwing.com/solution/content/5345/
在这里插入图片描述

N,V = map(int,input().split())
weight = []
val = []
for _ in range(N):
    wi,vi = map(int,input().split())
    weight.append(wi)
    val.append(vi)
# dp[i][j]代表使用前i个物品,针对容量j的最大价值
# dp[0][...] 为0, dp[...][0]为0
dp = [[0]*(V+1) for _ in range(N+1)]
"""
超时做法:
for i in range(1,N+1):
    for j in range(1,V+1):
        for k in range(j//weight[i-1]+1):
            dp[i][j] = max(dp[i][j], dp[i-1][j-k*weight[i-1]]+k*val[i-1])
"""
for i in range(1,N+1):
    for j in range(1,V+1):
        dp[i][j] = dp[i-1][j]
        if j>=weight[i-1]:
            dp[i][j] = max(dp[i][j], dp[i][j-weight[i-1]]+val[i-1])
# print(dp)
print(max(dp[N]))

在这里插入图片描述

其实0-1背包和完全背包的代码只有一句不同(注意dp):
0-1背包:

dp[i][w] = dp[i-1][w]
if w-weight[i-1]>=0:
    dp[i][w] = max(dp[i][w], dp[i-1][w-weight[i-1]]+val[i-1])

完全背包:

dp[i][j] = dp[i-1][j]
if j>=weight[i-1]:
    dp[i][j] = max(dp[i][j], dp[i][j-weight[i-1]]+val[i-1])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值