揹包問題小結

2021-10-08 01:34:18 字數 3238 閱讀 5869

學演算法的時候,揹包問題是乙個很常見的動態規劃問題,像什麼01揹包、完全揹包、多重揹包等,當時學的時候就有一些懵懵懂懂的,現在複習的時候又不會了,所以進行總結一下,方便日後檢視學習。問題基本上都是lintcode上面的題目,然後在github上還找到乙個專門講揹包問題的倉庫:

樣例 1:

輸入: [3,4,8,5], backpack size=10

輸出: 9

樣例 2:

輸入: [2,3,5,7], backpack size=12

輸出: 12

o(n x m) 的時間複雜度 and o(m) 空間複雜度

如果不知道如何優化空間o(n x m) 的空間複雜度也可以通過.

你不可以將物品進行切割。

public

class

solution

//當前容量下最大值

int[

]dp =

newint

[m+1];

for(

int i =

0; i < a.length; i++)}

return dp[m];}

}

這是乙個01揹包問題,但是不是那種特別純的01揹包問題,這個揹包沒有價值,最終的目的是我們裝的越多越好,所以我們可以把重量當作他的價值。01揹包主要就是選擇還是不選擇這個物件的問題,在**中我們先對物品的重量進行遍歷,然後再對容量進行遍歷,dp[j]表示當容量為j時,能夠裝得最滿的量。對應的狀態轉移方程如下:

d p[

j]

=dp[j](不選擇a[i]) \\ dp[j-a[i]]+a[i](選擇a[i]) \end \right.

dp[j]=

//容量

int[

]dp =

newint

[m+1];

for(

int i =

0; i < a.length; i++)}

return dp[m];}

}這是乙個01揹包問題,和上題相比有了價值這個陣列,但是思想一樣,所以只需要一點小改動就解決了。

給出 n 個物品, 以及乙個陣列, nums[i]代表第i個物品的大小, 保證大小均為正數並且沒有重複, 正整數 target 表示揹包的大小, 找到能填滿揹包的方案數。

每乙個物品可以使用無數次

給出四個物品, 大小為 [2, 3, 5, 7], 價值為 [1, 5, 2, 4], 和乙個大小為 10 的揹包. 最大的價值為 15.
package lintcode;

public

class

backpackiii

//容量

int[

]dp =

newint

[m+1];

for(

int i =

0; i < a.length; i++)}

return dp[m];}

public

static

void

main

(string[

] args)

;int

v =; system.out.

println

(b.backpackiii

(m,a,v));

}}

這一題是乙個完全揹包問題,物品是無限多,因為這題是vip才能寫的,所以我只能到網上搜這個題目自己寫一下,需要注意的點是這裡第二層迴圈採用正序遍歷,因為物品時無窮多的。這一題還可以使用貪婪演算法進行求解,就是找價效比最高的那個,我這裡的實現方法是採用動態規劃。

給出 n 個物品, 以及乙個陣列,nums[i]代表第i個物品的大小, 保證大小均為正數並且沒有重複, 正整數target表示揹包的大小, 找到能填滿揹包的方案數。

每乙個物品可以使用無數次

樣例1

輸入: nums = [2,3,6,7] 和 target = 7

輸出: 2

解釋:方案有:

[7][2, 2, 3]

樣例2

輸入: nums = [2,3,4,5] 和 target = 7

輸出: 3

解釋:方案有:

[2, 5]

[3, 4]

[2, 2, 3]

public

class

solution

//代表次數

int[

]dp =

newint

[target+1]

; dp[0]

=1;for

(int i =

0; i < nums.length; i++)}

return dp[target];}

}

這也是乙個完全揹包問題,但是又有點不同,是讓我們找出填滿揹包的方案數,我們將dp設定為次數,然後發現這也是乙個有最優子結構性質的問題。

給出 n 個物品, 以及乙個陣列,nums[i]代表第i個物品的大小, 保證大小均為正數, 正整數target表示揹包的大小, 找到能填滿揹包的方案數。

每乙個物品只能使用一次

給出候選物品集合[1,2,3,3,7]以及 target7

結果的集合為:

[7][1,3,3]

返回2

public

class

solution

int[

]dp =

newint

[target+1]

; dp[0]

=1;for

(int i =

0; i < nums.length; i++)}

return dp[target];}

}

有了上面的經驗我們只需要將揹包問題iv的**的第二層遍歷改為逆序就解決了

目前的問題就總結這麼多,後面有再接著新增。

揹包問題小結

這個周好好總結了揹包問題,下面簡單總結一下揹包問題,也方便以後忘了可以來複習 揹包問題最基礎的就是01揹包,其他的揹包問題都可以通過新增各種附加條件這樣的方式轉化為01揹包。01揹包就按字面意思來理解,每個物品只有一件,0是false1是true就是這件物品裝還是不裝,做出選擇,根據這個選擇我們也可...

揹包基礎小結

揹包學得太差了要好好複習總結一下 01 完全 揹包 揹包問題 有一些物品,每個物品有花費和價值,一般來說求的是在花費不超過給定數的前提下求最大的價值.一般來說會省略第一維,但是在一些問題轉化成的揹包問題中不要忘了這一維可能又會被利用起來.01揹包 v表示花費 w表示價值 go i,1,n yes j...

樹形揹包小結

已知 2 1 種做法 分別是 link bzoj2427 int sta n dfn n low n w n val n dp n 505 n,m,top,w n v n fa n l n cnt n siz n bel n idx vint g n bitsetins,vis void tarja...