寫在前面,如果有更好的方法可以給博主分享一下麼,木有vip,看不到lintcode的題解,謝謝啦
題目描述
https://www.lintcode.com/problem/backpack/description
在n個物品中挑選若干物品裝入揹包,最多能裝多滿?假設揹包的大小爲m,每個物品的大小爲A[i]
樣例
輸入:[3, 4, 8, 5], backpack size = 10
輸出:9
挑戰
O(n x m) time and O(m) memory.
題解
方法一:遞歸
暴力求解所有可能性,自頂向下
_helper(self, w, index, c)函數,表示考慮求解將[0,index]的物品放入容量爲c的揹包中,能得出的最大容量,遞歸函數,其中index,表示考慮將[0, index]的物品放入容量爲c的揹包,c-表示剩餘容量,故是最終結果,其表示將所有物品考慮放入容量爲m的揹包中的最大值。
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):
if not A or m <= 0:
return 0
return self._helper(A, len(A) - 1, m)
def _helper(self, w, index, c):
if index < 0 or c < 0:
return 0
res = 0
for i in range(0, index + 1):
res = max(res, self._helper(w, i - 1, c))
if c - w[i] >= 0:
res = max(res, self._helper(w, i - 1, c - w[i]) + w[i])
return res
方法二:記憶化搜索
水到渠成的記憶化搜索
class Solution:
def __init__(self):
self.memo = []
def backPack(self, m, A):
if not A or m <= 0:
return 0
self.memo = [[-1] * (m + 1) for _ in range(len(A))]
return self._helper(A, len(A) - 1, m)
def _helper(self, w, index, c):
if index < 0 or c > m:
return 0
if self.memo[index][c] != -1:
return self.memo[index][c]
res = 0
for i in range(0, index + 1):
res = max(res, self._helper(w, i - 1, c))
if c - w[i] >= 0:
res = max(res, self._helper(w, i - 1, c - w[i]) + w[i])
self.memo[index][c] = res
return res
方法三:動態規劃
時間和空間複雜度均爲,n-表示物品數,m-表示容量
class Solution:
def backPack(self, m, A):
if not A or m <= 0:
return 0
dp = [[0] * (m + 1) for _ in range(len(A))]
for j in range(m + 1):
if j >= A[0]:
dp[0][j] = A[0]
for i in range(1, len(A)):
for j in range(m + 1):
dp[i][j] = dp[i-1][j]
if j - A[i] >= 0:
dp[i][j] = max(dp[i][j], dp[i - 1][j - A[i]] + A[i])
return dp[-1][-1]
空間的優化,時間複雜度,空間複雜度
因爲上面的dp[i][j],只用到了,dp[i-1][j]及其左側元素,不涉及右側元素,故可以只用的空間複雜度,從右側開始更新,且還可以提前終止。
class Solution:
def backPack(self, m, A):
if not A or m <= 0:
return 0
dp = [0] * (m + 1)
for i in range(0, len(A)):
j = m
while j >= A[i]:
dp[j] = max(dp[j], dp[j - A[i]] + A[i])
j -= 1
return dp[-1]