九章演算法 微軟面試題 揹包問題 V

2021-10-11 17:50:50 字數 1763 閱讀 6336

給出 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 隨機跳轉到兩個標籤中的...