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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

01背包问题从简单到复杂

發(fā)布時(shí)間:2024/9/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 01背包问题从简单到复杂 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目:

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

狀態(tài)轉(zhuǎn)移方程:

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

基于遞歸的實(shí)現(xiàn):

這里的出口容易搞錯(cuò),出口可以從遞推方程成立條件來(lá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])

基于第一種遞歸的自下而上和自上而下實(shí)現(xiàn):

# 后來(lái)仔細(xì)考慮出后之后,做了如下修正: 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背包問(wèn)題的一維數(shù)組方式實(shí)現(xiàn)

凡是基于去與不去的問(wèn)題,均可使用如下方式

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背包問(wèn)題可行性問(wèn)題

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

這是為什么呢?可以這樣理解:初始化的 F 數(shù)組事實(shí)上就是在沒(méi)有任何物品可以放入背包時(shí)的合法狀態(tài)。 如果要求背包恰好裝滿,那么此時(shí)只有容量為 0 的背包可以在什么也不裝且價(jià)值為 0 的情況下被“恰好裝滿”, 其它容量的背包均沒(méi)有合法的解,屬于未定義的狀態(tài),應(yīng)該被賦值為-∞了。 如果背包并非必須被裝滿,那么任何容量的背包都有一個(gè)合法解“什么都不裝”,這個(gè)解的價(jià)值為 0 , 所以初始時(shí)狀態(tài)的值也就全部為 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]

運(yùn)行結(jié)果:

#%% 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

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。