在n個物品中挑選若干物品裝入揹包,最多能裝多滿?假設揹包的大小為m,每個物品的大小為a[i]
示例:
樣例 1:
輸入: [3,4,8,5], backpack size=10
輸出: 9
樣例 2:
輸入: [2,3,5,7], backpack size=12
輸出: 12
首先要明確一點,在揹包問題中,陣列大小和總稱重有關。
給定n個物品,重量分別為正整數a0, a1, …, an-1。乙個揹包最大承重是m,物品的重量都是整數。每個裝物品的方案的總重量都是0到m。如果對於每個總重量,我們能知道有沒有方案能做到,就可以解決。
需要知道n個物品是否能拼出重量w(w=0,1……)。最後一步:最後乙個物品是否進入揹包。
情況1:如果前n-1個物品能夠拼出w,那麼前n個物品也能拼出w
情況2:如果前n-1個物品能拼出w-an-1,再加上最後的物品an-1,拼出w
因此我們可以假設狀態f[i][w]表示能否用前i個物品拼出重量w
假設狀態f[i][w]表示能否用前i個物品拼出重量w
初始條件:
f[0][0]=true:0個物品可以拼出重量0
f[0][1……m]=false:0個物品不能拼出大於0的重量
邊界情況:
f[i-1][w-ai-1]只能在w>ai-1時使用
逐行計算,時間複雜度:o(mn),空間複雜度:優化後 可以達到o(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
"""defbackpack
(self, m, a)
:# write your code here
if m==0or
len(a)==0
:return
0 dp=[[
false]*
(m+1
)for i in
range
(len
(a)+1)
] dp[0]
[0]=
true
for i in
range(1
,len
(a)+1)
:for j in
range
(m+1):
dp[i]
[j]=dp[i-1]
[j]if j>=a[i-1]
: dp[i]
[j]=dp[i]
[j]or dp[i-1]
[j-a[i-1]
] res=
0for i in
range
(m,-1,
-1):
if dp[
len(a)
][i]
==true
: res=i
break
return res
#下面的方法是採用滾動陣列去優化,我之前一直沒搞懂為什麼要逆序,後面才知道舉個例子假設我們要計算f ( i , 4 ) f(i,4)f(i,4),我們需要用到的值為f ( i − 1 , 4 ) f(i-1,4)f(i−1,4)和f ( i − 1 , 4 − w ( i ) ) f(i-1,4-w(i))f(i−1,4−w(i)),因此為了防止結果被覆蓋,我們需要從後向前依次計算結果
if m==0:
return
0 n=
len(a)
dp=[0
]*(m+1
)for i in
range(1
,n+1):
for j in
range
(m,-1,
-1):
#逆序if j>=a[i-1]
: dp[j]
=max
(dp[j]
,dp[j-a[i-1]
]+a[i-1]
)else
:break
print
(dp)
return dp[m]
揹包型動態規劃 揹包問題3
給定n種物品,每種物品都有無限個.第i個物品的體積為a i 價值為v i 再給定乙個容量為m的揹包.問可以裝入揹包的最大價值是多少?樣例 1 輸入 a 2,3,5,7 v 1,5,2,4 m 10 輸出 15 解釋 裝入三個物品 1 a 1 3,v 1 5 總價值 15.樣例 2 輸入 a 1,2,...
揹包型動態規劃 揹包問題6
給出乙個都是正整數的陣列nums,其中沒有重複的數。從中找出所有的和為target的組合個數。示例 輸入 nums 1,2,4 和 target 4 輸出 6 解釋 可能的所有組合有 1,1,1,1 1,1,2 1,2,1 2,1,1 2,2 4 和揹包問題5唯一的區別是 組合中數字可以按照不同的順...
動態規劃揹包問題 01揹包
問題描述 n種物品,每種乙個。第i種物品的體積為vi,重量為wi。選一些物品裝到容量為c的揹包,使得揹包內物品不超過c的前提下,重量最大。問題分析 宣告乙個f n c 的陣列。f i j 表示把前i件物品都裝到容量為j的揹包所獲得的最大重量。當 j v i 時,揹包容量不足以放下第 i 件物品,f ...