給出 n 個物品, 以及乙個陣列, nums[i] 代表第i個物品的大小, 保證大小均為正數, 正整數 target 表示揹包的大小, 找到能填滿揹包的方案數。(每乙個物品只能使用一次)
樣例
給出候選物品集合 [1,2,3,3,7] 以及 target 7
結果的集合為:
[7][1,3,3]
返回 2
演算法:dp(動態規劃)
題目描述
nums[i]表示第i個物品的大小 ;target 表示揹包的大小;每個物品只能使用一次;求裝滿揹包的方案數。
演算法思路
當不放第i個物品時 : dp[i][j] = dp[i - 1][j]
當放第i個物品時:dp[i][j] += dp[i - 1][j - nums[i - 1]]
**思路
當沒有物品時直接 return false
定義乙個二維陣列dp[i][j]來表示前i個物品重量有多少種方式組出重量j
兩層迴圈巢狀來實現
第一層迴圈列舉i表示前i個物品的重量
第二層迴圈列舉j表示重量
根據演算法思路中的狀態轉移方程來實現
dp[n][target]方案數
return dp[n][target]
複雜度分析
優化
fori1
tonold=
now;
now=1+
now;
forj0to
targetdp[
now][j]
=dp[old][j
]if(j
>=
nums[i
-1])dp
[now][j
]+=dp[
old][j-
nums[i
-1]];
原本是 老值 + 老值 = 新值,如果正著更新,可能會出現 老值 + 新值,所以需要倒著更新。dp[i][j] = dp[i-1][j] + dp[i-1][j - nums[i-1]],新值 = 兩個老值加起來
fori1
tonforj
targetto0
if(j>=
nums[i
-1])// old + old ==> new
// old1 = dp[j]
// old2 = dp[j - nums[i - 1]]dp[
j]+=dp[j
-nums[i
-1]];
優化後複雜度分析
public
class
solution
// dp[i][j]表示前i個數字有多少種方式拼出數字jint
dp=newint[n
+2][target+2
];// 初始化dp[i][j]
for(
inti=0
;i<=
target;i
++)else
}for
(inti=
1;i<=n;
i++)}}
returndp[
n][target];}
}
更多題解參考:九章演算法
九章演算法面試題58 揹包問題
有乙個大小為m 整數 的揹包,和n個體積為正整數的物品 大小分別為a i 將這個n個物品選一些裝到揹包中,請問最多能裝滿多少的體積?揹包問題是動態規劃問題的一種典型題目。動態規劃問題我們一般要考慮下面這四點。1.狀態 state 2.方程 function 3.初始化 intialization 4...
九章演算法 微軟面試題 公平索引
現在給你兩個長度均為n的整數陣列 a 和 b。當 a 0 a k 1 a k a n 1 b 0 b k 1 和 b k b n 1 四個和值大小相等時,稱索引k是乙個公平索引。也就是說,索引k 可以使得a,b 兩個陣列被分成兩個非空陣列,這四個子陣列的和值相等。例如,陣列a 4,1,0,3 b 2...
九章演算法 蘇州微軟面試題 程式檢查
描述 有一種程式語言,只有以下五種命令,每種命令最多有兩個引數,請檢查給定的程式是否可能無限迴圈。這些命令分別是 label 宣告乙個標籤,引數是乙個字串,且每個標籤只宣告一次。goto 跳轉到乙個標籤,並從標籤處開始按順序執行程式。halt 停機,程式終止。gotorand 隨機跳轉到兩個標籤中的...