国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

完全背包問題-含優化

2019-11-06 06:06:27
字體:
來源:轉載
供稿:網友
**題目**有N件物品和一個容量為V的背包,每件物品可無限次使用。第i件物品的所需容量是c[i],價值是w[i]。求解將哪些物品裝入背包可使價值總和最大。

由于物品可以無限次使用,商品i以及商品j,如果c[i]<=c[j] and w[i]>=w[j],那么如果要達到最大價值,無論如何都不必裝入物品j。商品優化代碼如下:

#coding=utf-8class Solution(): def full_package(self,goods,max_V): self.goods_remove(goods) PRint goods def goods_remove(self,goods): # 操作簡化,將所有的不符合條件的good刪除 good_delete = set([]) #方便查找,商品不必重復刪除 for i in range(len(goods)): #如果商品已經在刪除列表,那么沒必要再考慮比這個商品j還差勁的商品k,因為商品列表中一定存在i優于j,才導致j出現在刪除列表,商品k如果差于商品j,那么商品k一定差于商品i,即i優于k,k肯定也在刪除列表。。。 if i in good_delete:continue for j in range(len(goods)): if goods[i][0] <= goods[j][0] and goods[i][1] >= goods[j][1]: if j == i: continue good_delete.add(j) elif goods[i][0] >= goods[j][0] and goods[i][1] <= goods[j][1]: if j == i: continue good_delete.add(i) else:continue good_delete = list(good_delete) good_delete.sort(reverse=True) for i in good_delete: del goods[i]

完全背包問題有2種解法 解法1:采用01背包問題的相關思路,將所有物品的c[i]*2^k<=V,加入到goods中,因為c[i]*2^k組合可以滿足調用物品i的任意一種情況,相當于數字2進制表示。然后后續采用01背包問題完全一致的解法即可,解法1代碼如下:

#coding=utf-8class Solution(): def full_package(self,goods,max_V): self.goods_remove(goods) goods_add = [] for i in goods: k = 1 while i[0]*(2**k)<=max_V: goods_add.append([i[0]*(2**k),i[1]*(2**k)]) k+=1 goods.extend(goods_add) f = [0] * (max_V + 1) for i in range(len(goods)): for v in xrange(max_V,goods[i][0]-1,-1): #特別注意這個if語句,如果不寫,結果可能會出現錯誤!!! if v>=goods[i][0]: f[v] = max(f[v],f[v-goods[i][0]]+goods[i][1]) print f return f[max_V] def goods_remove(self,goods): # 操作簡化,將所有的不符合條件的good刪除 good_delete = set([]) for i in range(len(goods)): if i in good_delete: continue for j in range(len(goods)): if goods[i][0] <= goods[j][0] and goods[i][1] >= goods[j][1]: if j == i: continue good_delete.add(j) elif goods[i][0] >= goods[j][0] and goods[i][1] <= goods[j][1]: if j == i: continue good_delete.add(i) else:continue good_delete = list(good_delete) good_delete.sort(reverse=True) for i in good_delete: del goods[i]goods = [[5,12],[4,3],[7,10],[2,3],[6,6]]test = Solution()print test.full_package(goods,16)

結果如下所示: [0, 0, 3, 3, 6, 12, 12, 15, 15, 18, 24, 24, 27, 27, 30, 36, 36] 36


解法2:由于每個物品可以使用無限次,求解01背包問題時,value需要逆序計算,正式為了保證每件物品只可以選擇1次,無法無限次選用。正是由于物品可以使用無限次,完全背包問題其實只要對value順序進行計算,求出結果即可。代碼如下:

#coding=utf-8class Solution(): def full_package(self,goods,max_V): self.goods_remove(goods) f = [0] * (max_V + 1) for i in range(len(goods)): for v in range(max_V+1): #特別注意這個if語句,如果不寫,結果可能會出現錯誤!!! if v>=goods[i][0]: f[v] = max(f[v],f[v-goods[i][0]]+goods[i][1]) print f return f[max_V] def goods_remove(self,goods): # 操作簡化,將所有的不符合條件的good刪除 good_delete = set([]) for i in range(len(goods)): if i in good_delete: continue for j in range(len(goods)): if goods[i][0] <= goods[j][0] and goods[i][1] >= goods[j][1]: if j == i: continue good_delete.add(j) elif goods[i][0] >= goods[j][0] and goods[i][1] <= goods[j][1]: if j == i: continue good_delete.add(i) else: continue good_delete = list(good_delete) good_delete.sort(reverse=True) for i in good_delete: del goods[i]goods = [[5,12],[4,3],[7,10],[2,3],[6,6]]test = Solution()print test.full_package(goods,16)

結果如下所示: [0, 0, 3, 3, 6, 12, 12, 15, 15, 18, 24, 24, 27, 27, 30, 36, 36] 36


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 绩溪县| 邵阳县| 边坝县| 利川市| 巴彦县| 三河市| 嘉黎县| 旺苍县| 龙泉市| 汝南县| 仲巴县| 鄂托克旗| 天峻县| 东明县| 修文县| 酒泉市| 禄丰县| 嵊州市| 类乌齐县| 肇庆市| 正阳县| 呼图壁县| 星座| 西盟| 昌江| 涟源市| 蓬安县| 凌源市| 慈溪市| 丹江口市| 毕节市| 和政县| 双峰县| 五莲县| 金坛市| 健康| 天长市| 咸阳市| 康乐县| 乌拉特中旗| 旬阳县|