部分揹包問題快速查閱及空間優化

2021-09-17 23:38:47 字數 1742 閱讀 8888

** 假設我們有n件物品,分別編號為1, 2…n。其中編號為i的物品價值為vi,它的重量為wi。為了簡化問題,假定價值和重量都是整數值。現在,假設我們有乙個揹包,它能夠承載的重量是w。現在,我們希望往包裡裝這些物品,使得包裡裝的物品價值最大化,那麼我們該如何來選擇裝的東西呢?

話不多少直接進入正題

尋找遞推關係式,面對當前商品有兩種可能性:

第一,包的容量比該商品體積小,裝不下,此時的價值與前i-1個的價值是一樣的,即v(i,j)=v(i-1,j);

第二,還有足夠的容量可以裝該商品,但裝了也不一定達到當前最優價值,所以在裝與不裝之間選擇最優的乙個,即v(i,j)=max{ v(i-1,j),v(i-1,j-w(i))+v(i) }

其中v(i-1,j)表示不裝,v(i-1,j-w(i))+v(i) 表示裝了第i個商品,揹包容量減少w(i)但價值增加了v(i);

由此可以得出遞推關係式:

1) j2) j>=w(i) v(i,j)=max{ v(i-1,j),v(i-1,j-w(i))+v(i) }

在此give the code:

/*for (int i = 1; i <= number; i++)//空間優化前

}}*/

時間空間複雜度均為o(nv)

時間上幾乎無優化但空間上還有

!!!……

怎麼優化的呢?

b[j]表示j容量下存放的價值最大量。

為什麼j要逆序呢??

如果j不逆序而採用正序j=0…capacity,如上圖所示,當j=8時應該有b(8)=b(8-w(3))+v(3)=b(4)+5,然而此時的b(4)已經在j=4的時候被修改過了,原來的b(4)=4,現在b(4)=5,所以計算得出b(8)=5+5=10,(相當於3號物體放進兩次)顯然這於正確答案不符合;所以該一維陣列後面的值需要前面的值進行運算再改動,如果正序便利,則前面的值將有可能被修改掉從而造成後面資料的錯誤;相反如果逆序遍歷,先修改後面的資料再修改前面的資料,此種情況就不會出錯了。

給上**用於查閱:

#include #include #include using namespace std;

const int maxn = 100;//物品最大件數

const int maxv = 1000;//v的上限

int w[maxn], v[maxn];

int dp[maxn];

int main() //揹包問題

for (int i = 0; i < number; i++)

for (int i = 0; i <= capacity; i++)

/*for (int i = 1; i <= number; i++)//空間優化前

}}*/

for (int i = 1; i <= number; i++)//空間優化後

}} printf("%d", dp[capacity]);//輸出最大能裝價值

return 0;

}

完全揹包問題(空間優化,列印路徑)

hdu1114 寫在前面 這裡給出hdu1114題作為樣例 完全揹包問題 有n種物品,每i種物品的體積為vc i 價值為w i 數量不限 有一容量為c的揹包,問如何裝能使揹包的體積最大 當使用二維陣列時的狀態轉移方程為 dp i v max dp i 1 v dp i v vc i w i 空間優化...

01揹包問題 優化及變形

問題描述 有n件商品,第i件商品的重量是weights i 1 價值是values i 1 揹包容量是cap 則揹包能夠裝物品的最大價值首先構建乙個二維陣列dp,dp i j 表示第i件物品時揹包容量為j時的最大價值。如何求得dp i j 1 values i 1 j,說明第i件物品不能放入當前容量...

完全揹包問題 一維空間優化

有 n 種物品和乙個容量是 v 的揹包,每種物品都有無限件可用。第 i 種物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品種數和揹包容積。接下來有 n 行,每行兩個整數...