今天从后往前复习了,先巩固一下昨天的背包问题,毕竟昨天的代码是参考别人的,今天要自己写一遍。
2.01背包
1、还有一个状态f
2、直接用v[i]\w[i]接收就可以
3、j是从m开始的
N = 1010
n,m = map(int,input().split())
v = [0]*N
w = [0]*N
f = [0]*N
for i in range(n):
v[i],w[i] = map(int,input().split())
for i in range(n):
for j in range(m,v[i]-1,-1):
f[j] = max(f[j],f[j-v[i]]+w[i])
print(f[m])
3.完全背包
f可化简为一维
N = 1010
f = [0]*N
v = [0]*N
w = [0]*N
n,m = map(int,input().split())
for i in range(n):
v[i],w[i] = map(int,input().split())
for i in range(n):
for j in range(v[i],m+1):
f[j] = max(f[j],f[j-v[i]]+w[i])
print(f[m])
4.多重背包问题1–朴素版
居然按照自己的思路写出来了!!!说明理解了!!!开心!
N = 110
v = [0]*N
w = [0]*N
s = [0]*N
f = [[0]*N for _ in range(N)]
n,m = map(int,input().split())
for i in range(1,1+n):
v[i],w[i],s[i] = map(int,input().split())
for i in range(1,1+n):
for j in range(m+1):
for k in range(s[i]+1):
if k*v[i]<=j:
f[i][j] = max(f[i][j],f[i-1][j-k*v[i]]+k*w[i])
print(f[n][m])
5多重背包II——二进制优化
这个很不熟悉,其实具体原理就是把原来不同的物品根据个数划分为新的物品,然后用01背包,正好可以拼凑出原来的所有可能性
# 多重背包使用二进制进行优化
# 具体是先分好组,然后用01背包
N = 11010
M = 2010
v = [0]*N
s = [0]*N
w = [0]*N
f = [0]*N
n,m = map(int, input().split())
# 如何记录新的s[i]和与其对应的v[i]和w[i]。
# 通过一次次接收,而不是一下子接收
idx = 0
for _ in range(n):
a,b,s = map(int,input().split())
k = 1
while k<=s:
# 利用idx给物品重新编号,不同数量的同一物品,看做不同物品。
idx+=1
v[idx] = a*k
w[idx] = b*k
s -= k
k *= 2
if s>0:
idx += 1
v[idx] = a*s
w[idx] = b*s
n = idx
for i in range(1,1+n):
for j in range(m,v[i]-1,-1):
f[j] = max(f[j],f[j-v[i]]+w[i])
print(f[m])
9分组背包
非常混乱。题意理解错了,每组只能选一种,每种也只能选一个。
这是自己写的
N = 110
v = [[0]*N for _ in range(N)]
w = [[0]*N for _ in range(N)]
s = [0]*N
f = [[0]*N for _ in range(N)]
n,m = map(int,input().split())
for i in range(1,1+n):
s[i] = int(input())
for j in range(1,s[i]+1):
v[i][j],w[i][j] = map(int,input().split())
# 第i组物品
for i in range(1,1+n):
# 选其中的第k个
for k in range(1,s[i]+1):
# 背包体积为j
for j in range(1+m):
nums =0
if j>=v[i][k]*nums:
f[i][j] = max(f[i][j],f[i-1][j-v[i][k]*nums]+w[i][k]*nums)
nums += 1
else:
break
print(f[n][m])
嗯,理解题意后,又自己写了一下,效果还不错。
N = 110
v = [[0]*N for _ in range(N)]
w = [[0]*N for _ in range(N)]
s = [0]*N
f = [0]*N
n,m = map(int,input().split())
for i in range(1,1+n):
s[i] = int(input())
for j in range(1,s[i]+1):
v[i][j],w[i][j] = map(int,input().split())
for i in range(1,1+n):
for j in range(m,-1,-1):
for k in range(1,s[i]+1):
if j>=v[i][k]:
f[j] = max(f[j],f[j-v[i][k]]+w[i][k])
print(f[m])