揹包問題 01揹包,完全揹包,多重揹包

2021-08-27 06:00:11 字數 4127 閱讀 8500

有goods_num件物品,max_volume的最大裝載量,每種物品只有一件,每種物品都有對應的重量或者說體積volume[i],價值value[i],求解裝包的最大價值

假設目前已經有 i-1件物品裝在容量為 j 的揹包中,並且得到最大價值package[ i-1 ][ j ],當前裝第i件,那麼討論分兩個角度,如果第i個物品裝不入揹包,那麼最大價值不變。如果第i個物品可以放入,那麼如果揹包容量為 j-volume[i]的時候的最大裝包價值加上第i個物品價值大於package[i-1][j],那麼package[i][j]最大價值就更新了,否則就不裝i

得到狀態轉移方程:

a. volume[ i ] > j :package[ i-1 ][ j ]

b. j >= volume[ i ] :max( package[ i-1 ][ j-volume[i] ] +value[ i ], package[ i-1 ][ j ] )

#include#include#includeusing namespace std;

#define max_size 1024

int volume[max_size]; /*每個物品所佔空間(或重量)*/

int value[max_size]; /*物品價值*/

int package[max_size][max_size]; /*未優化,package[i][j] 表示前i個物品放入容量為j的購物車的最大價值*/

int max_volume, goods_num; /*最大容量,物品數量*/

void init()

void _01package() }}

void print_res() /*列印結果*/

} cout << endl;

}

在設計演算法時會發現,上一層的資料在本層中並沒有修改,而是作為狀態的記錄,而且本層當前index只會用到上一層index之前的資料,所以可以降成一維,稱為滾動陣列。並且要求每次都重後往前遍歷,避免重複疊包

#include#include#includeusing namespace std;

#define max_size 1024

int volume[max_size]; /*每個物品所佔空間(或重量)*/

int value[max_size]; /*物品價值*/

int _package[max_size]; /*優化後,package[i]表示容量i的購物車所獲得的最大價值*/

int max_volume, goods_num; /*最大容量,物品數量*/

void init()

void _01package_optimize() /*優化演算法*/

void print_res_optimize()

有goods_num件物品,max_volume的最大裝載量,每種物品數量無限,每種物品都有對應的重量或者說體積volume[i],價值value[i],求解裝包的最大價值

與01揹包的思路基本相似,不過重要的一點是,每種物品是無限的,所以揹包可以多填

得狀態轉移方程:

a. volume[ i ] > jpackage[i-1][ j ]

b. j>=volume[ i ] :max( package[ i-1 ][ j-m*volume[ i ] ] +m*value[ i ], package[ i-1 ][ j ] )

#include#include#includeusing namespace std;

#define max_size 1024

int volume[max_size]; /*每個物品所佔空間(或重量)*/

int value[max_size]; /*物品價值*/

int package[max_size][max_size]; /*未優化,package[i][j] 表示前i個物品放入容量為j的購物車的最大價值*/

int max_volume, goods_num; /*最大容量,物品數量*/

void init()

void total_package()

}}

#include#include#includeusing namespace std;

#define max_size 1024

int volume[max_size]; /*每個物品所佔空間(或重量)*/

int value[max_size]; /*物品價值*/

int _package[max_size]; /*優化後,package[i]表示容量i的購物車所獲得的最大價值*/

int max_volume, goods_num; /*最大容量,物品數量*/

void init()

void total_package_optimize() /*優化演算法*/

}void print_res_optimize()/*列印*/

有goods_num件物品,max_volume的最大裝載量,第i件物品有數量為num[i],每種物品都有對應的重量或者說體積volume[i],價值value[i],求解裝包的最大價值

其實就是在乙個展開的01揹包問題,比如有3件相同物品,不如將它展開成 1 1 1 形式,然後01裝包

狀態轉移方程:

a. volume[ i ] > j :package[ i-1 ][ j ]

b. j >= volume[i] :max( package[ i-1 ][ j-volume[ i ] ] +value[i], package[ i-1 ][ j ] )

只不過,對於物品數大於1的,需要展開num[i]次

#include#include#includeusing namespace std;

#define max_size 1024

int volume[max_size]; /*每個物品所佔空間(或重量)*/

int value[max_size]; /*物品價值*/

int num[max_size]; /*i物品的個數*/

int package[max_size]; /*優化後,package[i]表示容量i的購物車所獲得的最大價值*/

int max_volume, goods_num; /*最大容量,物品數量*/

void init()

void multi_package() }}

void print_res()

這時候想乙個問題,如果一件物品的數量很大很大,那麼,對於第三個迴圈需要跑的時間就很長,在前面說過,多重揹包是可拆成01揹包形式,那麼,何不提前處理 volume[max_size],value[max_size],將問題先轉成01揹包。

轉化時有技巧,運用快速冪的知識,將一件物品拆成 1,2,4.......,當然有個容易想的前提:1~n的數可由2的若干指數和表示

#include#include#includeusing namespace std;

#define max_size 1024

int op_vol[max_size]; /*優化後的物品體積*/

int op_val[max_size]; /*優化後的物品價值*/

int package[max_size]; /*揹包*/

int max_volume,goodsnum; /*揹包最大體積,原先的貨品數量*/

int op_goodsnum; /*優化後的物品數*/

void init() /*初始化*/

void multi_package()

}int main()

if(num>0)

}multi_package();

cout<

揹包問題 01揹包 完全揹包 多重揹包

01揹包和完全揹包的區別 01揹包的侷限在於每樣物品只有一種,每個物品都有乙個屬於自己的價值和重量,在給定的物品中選出揹包所能容納的最大重量,要求是價值最大 完全揹包與01揹包的不同在於完全揹包不限制每樣物品的個數,物品的價值和質量都與01揹包一樣,也同樣是求在給定大小的容量中,找出最大價值的選擇 ...

揹包問題(01揹包,完全揹包,多重揹包)

揹包問題 01揹包,完全揹包,多重揹包 近日為以下瑣事煩身 差不多要向學院提交專案申請了,本來是想做個多模式的im系統的,可是跟往屆通過審核的專案比起來,缺乏創新和研究價值,所以在文件上要多做手腳,花點心思。揹包問題,經典有揹包九講。不死族的巫妖王發工資拉,死亡騎士拿到一張n元的鈔票 記住,只有一張...

揹包問題 01揹包 多重揹包 完全揹包

0 1揹包問題是指每一種物品都只有一件,可以選擇放或者不放。jj w i v i,j max v i 1,j v i 1,j w i v i for int i 0 i n i 初始化第0列 v i 0 0 for int j 0 j c j 初始化第0行 v 0 j 0 for int i 1 i...