演算法-揹包問題-動態規劃
阿新 • • 發佈:2018-12-11
揹包問題
揹包問題分為三類
- 01揹包問題
- 完全揹包問題
- 變態揹包問題
解決的思路都是使用動態規劃,直接上程式碼。
#include <iostream> #include <algorithm> using namespace std; int V[5][9];//代表用二維陣列求解 int V_op[9];//代表用一維陣列求解 int w[] = { 0, 2, 3, 4, 5 };//代表物品佔用空間 int v[] = { 0, 3, 4, 5, 6 };//代表物品價值 int c[] = { 0, 3, 4, 4, 4 };//代表物品數量限制,比如第一件物品最多能拿兩件 void pack01(); void findConsist(int i, int j); void pack_op(); void pack_full(); void pack_extrme(); int main(){ //二維陣列,可以查詢包裡的物品 pack01(); //一維陣列,比二維陣列佔用空間更小,但是無法直接反解包中物品 pack_op(); //揹包完全問題,即每件物品可以有無限多個 pack_full(); //揹包問題變態版,即每件物品可以有多個,但是由數量限制 pack_extrme(); std::system("pause"); return 0; } void pack01(){ for (int i = 0; i <= 4; i++){ V[i][0] = 0; } for (int j = 0; j <= 8; j++){ V[0][j] = 0; } for (int i = 1; i <= 4; i++){ for (int j = 1; j <= 8; j++){ if (j < w[i]){ V[i][j] = V[i - 1][j]; } else{ V[i][j] = max(V[i - 1][j], V[i - 1][j - w[i]] + v[i]); } } }; cout << V[4][8] << endl; for (int i = 1; i <= 4; i++){ for (int j = 1; j <= 8; j++){ cout << V[i][j] << "\t"; } cout << endl; } findConsist(4, 8); } void findConsist(int i, int j){ if (i == 0){ return; } if (V[i][j] == V[i - 1][j]){ cout << "商品" << i << "不在包裡" << endl; findConsist(i - 1, j); } else{ cout << "商品" << i << "在包裡" << endl; findConsist(i - 1, j - w[i]); } } void pack_op(){ for (int i = 0; i < 9; i++){ V_op[i] = 0; } for (int i = 0; i < 5; i++){ for (int j = 8; j >= w[i]; j--){ V_op[j] = max(V_op[j], V_op[j - w[i]] + v[i]); } } for (int i = 1; i < 9; i++) cout << V_op[i] <<"\t"; cout << endl; } void pack_full(){ for (int i = 0; i < 9; i++){ V_op[i] = 0; } for (int i = 0; i < 5; i++){ for (int j = w[i]; j <= 8; j++){ V_op[j] = max(V_op[j], V_op[j - w[i]] + v[i]); } } for (int i = 1; i < 9; i++) cout << V_op[i] << "\t"; cout << endl; } void pack_extrme(){ for (int i = 1; i <= 4; i++) for (int j = 8; j >= 0; j--) for (int k = 1; k <= c[i]; k++){//c[i]代表每種物品的數量限制,比如物品2最多有兩個 if (j - k*w[i] < 0) break; V_op[j] = max(V_op[j], V_op[j - k*w[i]] + k*v[i]); } cout << V_op[8] << endl; }