題目來自lintcode
http://www.lintcode.com/zh-cn/problem/backpack/
一個傳統01背包問題的推廣,假如只考一個背包放物品之后的最終最大價值,不考慮具體選哪些物品放入,該如何實現?
最蠢最笨的辦法,那當然就是-老老實實的構造背包容量-物品矩陣,然后取出矩陣最上方最右的值即可:
代碼也非常易懂:
class Solution: # @param m: An integer m denotes the size of a backpack # @param A: Given n items with size A[i] # @return: The maximum size def backPack(self, m, A): res=[[0 for i in range(len(A)+1)] for j in range(m+1)] for i in range(1,m+1): for j in range(1,len(A)+1): if A[j-1]>i: res[i][j]=res[i][j-1] else: res[i][j]=max(res[i][j-1],res[i-A[j-1]][j-1]+A[j-1]) if len(res)>1: res=res[-2:] return res[-1][-1]
測試一下:

嗯哼,不炸內存才怪,顯然這種解法,對於這個問題來說浪費太嚴重:
人家只要最終的最大值,不care怎么選,所以實際上只有最頂一行最后一個值是有用的,其他的都不需要。
所以我開始的思路是,就初始化兩個長度為背包容量的數組,來回迭代,最后輸出最后一次迭代的數組的最后一個值
自己改代碼發現失敗,代碼是這么寫的:

於是到群里問了七月的許老師,許老師說給你個C++的解法你改成python吧,她給的C++是這樣:

我改成了python,代碼如下:
class Solution: # @param m: An integer m denotes the size of a backpack # @param A: Given n items with size A[i] # @return: The maximum size def backPack(self,m,A): can=[False for i in range(m+1)] can[0]=True big=0 for i in range(len(A)): j=big while j>=0: if can[j] and j+A[i]<=m: can[j+A[i]]=True j-=1 big+=A[i] if big>m: big=m while can[big]==False: big-=1 return big
嗯哼,牛逼了,3000ms順利AC,但說實話這思路真的還沒搞懂,寫把代碼貼在這兒,回頭研究,歡迎各位博友給點思路,討論一下~
