01揹包問題 優化及變形

2021-10-01 02:10:07 字數 4277 閱讀 3303

問題描述:有n件商品,第i件商品的重量是weights[i-1],價值是values[i-1],揹包容量是cap

則揹包能夠裝物品的最大價值

首先構建乙個二維陣列dp,dp[i][j]表示第i件物品時揹包容量為j時的最大價值。

如何求得dp[i][j]:

(1)values[i-1]>j,說明第i件物品不能放入當前容量為j的揹包,即不放入第i件商品:

d p[

i][j

]=dp

[i−1

][j]

dp[i][j]=dp[i-1][j]

dp[i][

j]=d

p[i−

1][j

](2)values[i-1]<=j,則第i件物品可以放入到容量為j時的揹包中,但是這時候需要考慮放進第i件物品的揹包中物品價值是否比不放時大:

d p[

i][j

]=ma

x(dp

[i−1

][j]

,dp[

i−1]

[j−w

eigh

ts[i

−1]]

+val

ues[

i−1]

)dp[i][j] = max(dp[i-1][j], dp[i-1][j-weights[i-1]]+values[i-1])

dp[i][

j]=m

ax(d

p[i−

1][j

],dp

[i−1

][j−

weig

hts[

i−1]

]+va

lues

[i−1

])max中的第一項表示不放,第二項表示放入第i件,放入第i件就需要把揹包騰出至少weights[i-1]的容量,舉個例子:weights = ;values = ;當i=2,j=4時,此時需要放入揹包的物品重量為4,價值為4,而dp[i-1][j] = 2,所以需要將第一件重量為3價值為2的商品拿出,放入第2件商品,即dp[2][4] = dp[1][0]+4 = 4。

/*

* 01揹包:揹包可裝的最大價值

* @param 商品重量

* @param 商品價值

* @param 揹包容量

*/public int maxvalue

(int[

] weights, int[

] values, int cap)

if(weights.length != values.length)

int num = weights.length;

int[

] dp =

newint

[num+1]

[cap+1]

;for

(int i =

1; i <= num; i++

)else}}

return dp[num]

[cap]

;}

進行優化:

不難看出dp[i]只和dp[i-1]有關,因此可以使用兩個一維陣列來代替二維陣列進行動態規劃的迭代,空間複雜度由o(n*cap)降低為o(cap)。

public int maxvalue

(int[

] weights, int[

] values, int cap)

if(weights.length != values.length)

int num = weights.length;

int[

] dp1 =

newint

[cap+1]

; int[

] dp2 =

newint

[cap+1]

;for

(int i =

1; i <= num; i++

)else

} dp1 = dp2.

clone()

;}return dp2[cap]

;}

實際上還可以進行優化,只使用乙個一維陣列即可,空間複雜度仍然是o(cap)。不難看出dp2[j]在更新時只和dp1[0…j-1]有關,而不會使用dp1[j…cap],因此可以逆序對dp2進行更新:

int[

] dp2 =

newint

[cap+1]

;for

(int i =

1; i <= num; i++

)else}}

return dp2[cap]

;

上述描述不要求恰好裝滿揹包,如果要求恰好裝滿揹包的前提下,求揹包所能裝物品的最大價值,只需要修改初始化條件即可:j = 0時,dp為0,其他都為-∞。

int[

] dp2 =

newint

[cap+1]

;for

(int i =

1; i <= cap; i++

)

如果無法恰好裝滿揹包,則會返回乙個很大的負數。

原因:如果要求恰好裝滿,只有容量為0的時候什麼也沒裝是恰好裝滿的,而其他容量初始時不符合要求,所以應該賦值為-∞,從下面的例子可以看出,沒有恰好裝滿時,其價值是乙個很大的負數。

揹包容量為10

;int[

] weights =

;int[

] values =

;// 沒有合法解[0

,-2147483648,-

2147483648,2

,-2147483646,-

2147483646,-

2147483646,-

2147483646,-

2147483646,-

2147483646,-

2147483646][

0,-2147483648,-

2147483648,2

,4,-

2147483644,-

2147483644,6

,-2147483642,-

2147483642,-

2147483642][

0,-2147483648,-

2147483648,2

,4,-

2147483644,-

2147483644,6

,4,-

2147483642,-

2147483642][

0,-2147483648,-

2147483648,2

,4,-

2147483644,-

2147483644,6

,4,-

2147483642,-

2147483642][

0,-2147483648,-

2147483648,2

,4,2

,-2147483644,6

,4,6

,-2147483642

]int[

] weights =

;int[

] values =

;// 有解,為10[0

,-2147483648,-

2147483648,2

,-2147483646,-

2147483646,-

2147483646,-

2147483646,-

2147483646,-

2147483646,-

2147483646][

0,-2147483648,-

2147483648,2

,4,-

2147483644,-

2147483644,6

,-2147483642,-

2147483642,-

2147483642][

0,-2147483648,-

2147483648,4

,4,-

2147483644,6

,8,-

2147483640,-

2147483640,10

][0,

-2147483648,3

,4,4

,7,7

,8,9

,11,10

][0,

-2147483648,3

,4,4

,7,7

,8,9

,11,10

]

01揹包問題變形

一 問題 二 解題思路 三 c 下面是我自己理解寫的,沒有根據標準答案的,那答案在講啥?一直沒法ac,不過還是可以解決問題的。n件物品按單位重量價值降序排序,然後回溯法裝,右結點必要時剪枝,剛好湊成重量為m的若干件物品才能得到乙個解。include define max 50 using names...

01揹包變形

傳送門 現有n個物品,序號分別為1,2,n。對於每個i 1 i n 物品i有乙個體積wi和乙個價值vi。小明想在這n個物品中選取一些放到揹包裡帶回家。已知揹包的容積為w,這意味著所帶物品的總體積不能超過w。求出小明可以帶回家的物品總價值可能的最大值。constraints input 標準輸入格式如...

01揹包 問題變形 飯卡

example hdu 2546 解 利用 01揹包 狀態方程 f v max f v f v ci wi 1 對這個問題來說,干擾項是最後的5元,可以買任何一道菜,所以可以先用5元買最貴的一道菜 反正買最後一道菜時至少要有5元餘額,不如先不考慮這5元 去掉干擾項後就是乙個 01 問題了。2 一道菜...