有 N 種物品和一個容量爲 V 的揹包。第 i 種物品最多有 M i 件可用,每件耗費的空間是 C i ,價值是 W i 。求解將哪些物品裝入揹包可使這些物品的耗費的空間總和不超過揹包容量,且價值總和最大。
F [i , v] = max {F [i − 1, v − k ∗ C i ] + k ∗ W i | 0 ≤ k ≤ M i }
複雜度是 O(V ΣM i ) 。
看見了沒是不是很像完全揹包問題,所以他們可以相同的處理。
# F [i , v] = max {F [i − 1, v − k ∗ C i ] + k ∗ W i | 0 ≤ k ≤ M i } import numpy as np def pack_multiple_Bottom_up(N,V,C,W,M): list = np.zeros((N+1,V+1),dtype=int) for i in range(1,N+1): for j in range(0,V+1): t = min(j // C[i-1],M[i-1]) result = -1000 for k in range(t+1): A = list[i-1,j-k*C[i-1]] + k*W[i-1] if A > result: result = A list[i,j] = result return list[N,V]
def change_multiple_to_01(N,V,C,W,M): C_ =[] W_ =[] for i in range(N): t = min(V // C[i],M[i]) k = 1 j = t while 2*k <= t: C_.append(k*C[i]) W_.append(k*W[i]) j -= k k *= 2 C_.append(j*C[i]) W_.append(j*W[i]) def pack_0_1_first(N,V,C,W): F =[0]*(V+1) for i in range(1,N+1): for v in range(V,C[i-1]-1,-1): F[v] = max(F[v],F[v-C[i-1]] + W[i-1]) return F[V] N_ = len(C_) return pack_0_1_first(N_,V,C_,W_)
import numpy as np def change_multiple_to_01_yes_or_no(N,V,C,M): C_ =[] for i in range(N): t = min(V // C[i],M[i]) k = 1 j = t while 2*k <= t: C_.append(k*C[i]) j -= k k *= 2 C_.append(j*C[i]) def pack_0_1_first(N,V,C): F =[False]*(V+1) F[0] = True for i in range(1,N+1): for v in range(V,C[i-1]-1,-1): F[v] = F[v] or F[v-C[i-1]] return F[V] N_ = len(C_) return pack_0_1_first(N_,V,C_)
def pack_multiple_yes_or_no(N,V,C,M): list = np.zeros((N+1,V+1),dtype=int) list[:,:] = -1 list[0,0] = 0 for i in range(1,N+1): for j in range(V+1): if list[i-1,j] >=0: list[i,j] = M[i-1] else: list[i,j] = -1 for j in range(V-C[i-1]+1): if list[i,j] >0: list[i,j+C[i-1]] = max(list[i,j+C[i-1]],list[i,j]-1) #list[i,j]-1 # return list[N,V]