混合揹包 經典DP問題

2021-09-22 08:24:11 字數 1846 閱讀 1777

有 n 種物品和乙個容量是 v 的揹包。

物品一共有三類:

求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。

輸出最大價值。

輸入格式

第一行兩個整數,n,v,用空格隔開,分別表示物品種數和揹包容積。

接下來有 n 行,每行三個整數 vi,wi,si,用空格隔開,分別表示第 i 種物品的體積、價值和數量。

si=−1 表示第 i 種物品只能用1次;

si=0 表示第 i 種物品可以用無限次;

si>0 表示第 i 種物品可以使用 si 次;

輸出格式

輸出乙個整數,表示最大價值。

資料範圍

輸入樣例

4 5

1 2 -1

2 4 1

3 4 0

4 5 2

輸出樣例

8
混合揹包問題就是01揹包+完全揹包+多重揹包問題,根據物品的數量確定用哪種揹包問題進行求解

下面給出兩種解法組合

01揹包滾動陣列法+完全揹包滾動陣列法+多重揹包二進位制優化法

#include

using

namespace std;

#define max(a, b) ((a > b) ? (a) : (b))

const

int arrmax

;int dp[arrmax]

, que[arrmax]

, book[arrmax]

;int

main

(int argc,

char

**ar**)

else}}

} cout << dp[v]

<< endl;

return exit_success;

}

01揹包滾動陣列法+完全揹包滾動陣列法+多重揹包單調佇列優化法

#include

using

namespace std;

#define max(a, b) ((a > b) ? (a) : (b))

const

int arrmax

;int dp[arrmax]

, que[arrmax]

, book[arrmax]

;int

main

(int argc,

char

**ar**)

, tail

;for

(int jnd =

0; jnd <=

(v - ind)

/ v;

++jnd)

;while

(head < tail && que[tail -1]

<= temp)

--tail;

book[tail]

= jnd;

que[tail++

]= temp;

if(book[head]

< jnd - s)

++head;

dp[ind + jnd * v]

= que[head]

+ jnd * w;}}

} cout << dp[v]

<< endl;

return exit_success;

}

混合揹包問題

如果將p01 p02 p03混合起來。也就是說,有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的次數有乙個上限 多重揹包 應該怎麼求解呢?考慮到在p01和p02中給出的偽 只有一處不同,故如果只有兩類物品 一類物品只能取一次,另一類物品可以取無限次,那麼只需在對每個物...

混合揹包問題

name 混合揹包問題 author 巧若拙 date 07 06 18 09 33 description 混合揹包問題 在n種物品中選取若干件放在容量為c的揹包裡,分別用p i 和w i 儲存第i種物品的價值和重量。有的物品只可以取一次 01揹包 有的物品可以取無限次 完全揹包 有的物品可以取的...

混合揹包問題

有 n 種物品和乙個容量是 v 的揹包。物品一共有三類 第一類物品只能用1次 01揹包 第二類物品可以用無限次 完全揹包 第三類物品最多只能用 si 次 多重揹包 每種體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。輸出最大價值。輸入格式 第一行兩...