01背包x

经典01背包

问题描述:
给定 n 件物品,物品的重量为 w[i],物品的价值为 v[i]。现挑选物品放入背包中,假定背包能承受的最大重量为 c,问应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?

首先输入共n个物品,一个容量为v的背包,n和v没有协同关系,只是制约关系
再输入[各物品重量,各物品价值]
分别存入重量数组与价值数组
本题以n,v=4,5 ,输入(1,2)(2,4)(3,4)(4,5)为例

4 5
1 2
2 4
3 4
4 5

总代码 and 模板

遍历:先物品 后背包容量
因为要先开始物品,所以dp初始化:行是物品,行中的列是背包容量

N,V=map(int,input().split()) #物品数量、背包容量
weight=[0]
val=[0]
for i in range(N):
    wi,vi=map(int,input().split())
    weight.append(wi)
    val.append(vi)
dp = [[0]*(V+1) for _ in range(N+1)] #N行,V列
for i in range(1,N+1):#先物品、后背包容量
    for j in range(1,V+1):
        if j-weight[i]<0:
            dp[i][j]=dp[i-1][j]
        else:
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+val[i])
print(dp[N][V])

细节

注意是先重量,后价值。不要弄混了而加错了集合

N,V = map(int,input().split())
weight = []
val = []
for _ in range(N):
    wi,vi = map(int,input().split())
    weight.append(wi)
    val.append(vi)

weight=[1,2,3,4]
value = [ 2,4,4,5]

初始化dp数组:
dp = [ [0]*(V+1) for _ in range(N+1) ]
因为存在【没有物品,但有容量】与【有物品,容量不够】的情况,所以保留0数组
又因需要到达n,则range(N+1)
则五行六列
在这里插入图片描述
行:前4件物品
列:容量为1到5的书包

遍历背包,遍历
{ weight[i] , value[i] }与dp之间的关系:
dp通过 【i-1,{ 减weight[i] } + value[i]} 】 到达 下一个dp

for i in range(1,N+1):
    for w in range(1,V+1):
        if w<weight[i-1]:         #给的容量不够装下 该重量的物品,则到前一件里找适不适合
            dp[i][w] = dp[i-1][w]
        #若装的下且取到了i:
        #dp[i][w]
        else:					  
            dp[i][w] = max(dp[i-1][w-weight[i-1]]+val[i-1], dp[i-1][w])

为什么是i-1呢?因为保留0的原因,导致i相比 与 相对应的 value大1,

采药问题

在这里插入图片描述
输入:

70 3
71 100
69 1
1 2

输出:

3
T,M=map(int,input().split())#时间、药草数
time=[0]
val=[0]
for i in range(M):
    ti,vi=map(int,input().split())
    time.append(ti)
    val.append(vi)
dp=[[0]*(T+1) for i in range(M+1)]
for i in range(1,M+1):
    for j in range(1,T+1):
        if j<time[i]:
            dp[i][j]=dp[i-1][j]
        else:
            dp[i][j]=max(dp[i-1][j],dp[i-1][j-time[i]]+val[i])
print(dp[M][T])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值