日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

01背包问题从简单到复杂

發布時間:2024/9/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 01背包问题从简单到复杂 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目:

有 N 件物品和一個容量為 V 的背包。放入第 i 件物品耗費的費用是 C i 1 ,得到
的價值是 W i 。求解將哪些物品裝入背包可使價值總和最大。

狀態轉移方程:

F [i, v] = max {F [i ? 1, v], F [i ? 1, v ? C i ] + W i }

基于遞歸的實現:

這里的出口容易搞錯,出口可以從遞推方程成立條件來考慮

def pack_0_1_Rec2(N,V,C,W):if N == 0 :return 0if V < C[N-1]:return pack_0_1_Rec(N-1,V,C,W)return max(pack_0_1_Rec(N-1,V,C,W),pack_0_1_Rec(N-1,V-C[N-1],C,W) + W[N-1])

基于第一種遞歸的自下而上和自上而下實現:

# 后來仔細考慮出后之后,做了如下修正: def pack_0_1_Top_down(N,V,C,W):list = [[-1]*(V+1) for i in range(N+1)] # mins = min(C) # for i in range(N+1): # for j in range(V+1): # if i == 0 or j< mins: # list[i][j] =0list[0] = [0]*(V+1)def pack_0_1_Top_down_(N,V): # if list[N][V] == -1 and N >=1 and V >=mins:if list[N][V] == -1 and N >=1:A = pack_0_1_Top_down_(N-1,V) if V < C[N-1]: return Aelse:list[N][V] = max(A,pack_0_1_Top_down_(N-1,V-C[N-1])+W[N-1])return list[N][V]return pack_0_1_Top_down_(N,V)def pack_0_1_bottom_up(N,V,C,W):list = [[-1]*(V+1) for i in range(N+1)]list[0] = [0]*(V+1)for i in range(1,N+1):for j in range(0,V+1):A = list[i-1][j] if j < C[i-1]: list[i][j] = A else:list[i][j] = max(A,list[i-1][j-C[i-1]]+W[i-1]) # print list return list[N][V]

01背包問題的一維數組方式實現

凡是基于去與不去的問題,均可使用如下方式

def pack_0_1_first(N,V,C,W):def ZeroOnePack(F,ci,wi):for v in range(V,ci-1,-1):F[v] = max(F[v],F[v-ci] + wi)return FF =[0]*(V+1)for i in range(1,N+1):ZeroOnePack(F,C[i-1],W[i-1])return F[V]

01背包問題可行性問題

可行性問題,想清楚初始條件
如果是,要求恰好裝滿背包,那么在初始化時除了 F [0] 為 0 ,其
它 F [1…V ] 均設為 ?∞ ,這樣就可以保證最終得到的 F [V ] 是一種恰好裝滿背包的最優解。
如果并沒有要求必須把背包裝滿,而是只希望價格盡量大,初始化時應該將 F [0…V ] 全部設為 0 。

這是為什么呢?可以這樣理解:初始化的 F 數組事實上就是在沒有任何物品可以放入背包時的合法狀態。 如果要求背包恰好裝滿,那么此時只有容量為 0 的背包可以在什么也不裝且價值為 0 的情況下被“恰好裝滿”, 其它容量的背包均沒有合法的解,屬于未定義的狀態,應該被賦值為-∞了。 如果背包并非必須被裝滿,那么任何容量的背包都有一個合法解“什么都不裝”,這個解的價值為 0 , 所以初始時狀態的值也就全部為 0 了。 def pack_0_1_yes_or_no(N,V,C):def ZeroOnePack(F,ci):for v in range(V,ci-1,-1):F[v] = F[v-ci] or F[v]return FF =[-1]*(V+1)F[0] = Truefor i in range(1,N+1):ZeroOnePack(F,C[i-1])return F[V]

運行結果:

#%% N = 6 V = 23 C = [1,3,4,5,17,11] W = [2,9,7,5,11,4] #%% print pack_0_1_Rec(N,V,C,W) print pack_0_1_first(N,V,C,W) print pack_0_1_Top_down(N,V,C,W) print pack_0_1_bottom_up(N,V,C,W) print pack_0_1_Rec2(N,V,C,W) print pack_0_1_yes_or_no(N,V,C) 25 25 25 25 25 True

總結

以上是生活随笔為你收集整理的01背包问题从简单到复杂的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。