問題描述:有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 一道菜...