問題說明
有N件物品和一個(gè)容量為V的背包。
第i件物品的重量是w[i],價(jià)值是v[i]。
求解將哪些物品裝入背包可使這些物品的重量總和不超過背包容量,
且價(jià)值總和最大。
功能說明
本程序用動態(tài)規(guī)劃的思想解決了背包問題,并用了兩種算法:迭代法、遞歸法。在迭代法中實(shí)現(xiàn)了打印背包問題的表格。
代碼簡述
通過用戶輸入數(shù)據(jù),程序輸入檢測,動態(tài)分配空間,選擇算法, 用動態(tài)規(guī)劃的思想求解背包問題。
迭代法:
通過遍歷n行W列,迭代每行每列的值,并把最優(yōu)解放到 n行(在數(shù)組中為第n+1行)W列(在數(shù)組中為第W+1列)中。
遞歸法:
通過每次返回前i個(gè)物品和承重為j的最優(yōu)解, 遞歸計(jì)算總背包問題的最優(yōu)解。
源碼示例
using namespace std;int **T = NULL; // 存儲背包問題表格的數(shù)組指針// 返回兩個(gè)值的最大值int max(int a, int b) {return (a > b) ? a : b;}// 迭代法,能顯示背包問題的表格int packIterative(int n, int W, int *w, int *v) {// 循環(huán)遍歷n行for (int i = 1; i <= n; ++i){// 循環(huán)遍歷W列for (int j = 1; j <= W; ++j){//第i個(gè)物品能裝下,則比較包括第i個(gè)物品和不包括第i個(gè)物品,取其最大值if (w[i] <= j)T[i][j] = max(v[i] + T[i - 1][j - w[i]], T[i - 1][j]);// 第i個(gè)物品不能裝下,則遞歸裝i-1個(gè)elseT[i][j] = T[i - 1][j];}}return T[n][W];}// 遞歸法,不支持顯示背包問題的表格int packRecursive(int n, int W, int *w, int *v) {// 結(jié)束條件(初始條件),i或者j為0時(shí)最大總價(jià)值為0if (n == 0 || W == 0) {return 0;}// 第i個(gè)物品不能裝下,則遞歸裝i-1個(gè)if (w[n] > W) {return packRecursive(n - 1, W, w, v);}//第i個(gè)物品能裝下,則比較包括第i個(gè)物品和不包括第i個(gè)物品,取其最大值else {return max(v[n] + packRecursive(n - 1, W - w[n], w, v), packRecursive(n - 1, W, w, v));}}// 打印背包問題的表格void printT(int n, int W){// 打印n行for (auto i = 0; i <= n; i++){// 打印行數(shù)cout << i << ": ";// 打印W列for (int w = 0; w <= W; w++){cout << T[i][w] << " ";}// 換行cout << endl;}}int main() {int *w = NULL; // 存儲每件物品重量的數(shù)組指針int *v = NULL; // 存儲每件物品價(jià)值的數(shù)組指針int n; // 物品個(gè)數(shù)nint W; // 背包總承重Wcout << "---------------- 背包問題 ----------------" << endl;cout << "請輸入物品數(shù) n (n>=0) " << endl;// 輸入背包數(shù)cin >> n;if (cin.fail() || n < 0){cout << "輸入n錯(cuò)誤!" << endl;system("pause");return 0;}cout << "請輸入背包承重量 W (W>=0) " << endl;// 輸入背包承重量cin >> W;if (cin.fail() || W < 0){cout << "輸入W錯(cuò)誤!" << endl;system("pause");return 0;}// 分配空間// 對w和v分配n+1大小w = new int[n + 1];v = new int[n + 1];// 對T分配n+1行,并初始化為0T = new int *[n + 1]();// 對T分配W+1列,并初始化為0for (auto i = 0; i <= n; i++){T[i] = new int[W + 1]();}// 輸入背包的重量和價(jià)值for (auto i = 1; i <= n; i++){cout << "請輸入第 " << i << " 個(gè)物品的重量和價(jià)值(用空格隔開)" << endl;cin >> w[i] >> v[i];if (cin.fail() || w[i] < 0 || v[i] < 0){cout << "輸入錯(cuò)誤!" << endl;system("pause");return 0;}}cout << "------------------------------------------------" << endl;cout << "請選擇算法:" << endl;cout << "【1】迭代法" << endl;cout << "【2】遞歸法" << endl;cout << "------------------------------------------------" << endl;int choose;// 輸入算法的選擇cin >> choose;switch (choose){case 1:{// 迭代法,能顯示背包問題的表格cout << "能裝下物品的最大價(jià)值為 " << packIterative(n, W, w, v) << endl;cout << "------------------------------------------------" << endl;printT(n, W);break;}case 2:{// 遞歸法,不支持顯示背包問題的表格cout << "能裝下物品的最大價(jià)值為 " << packRecursive(n, W, w, v) << endl;break;}default:{cout << "輸入錯(cuò)誤!" << endl;break;}}cout << "------------------------------------------------" << endl;delete w;delete v;for (int i = 0; i <= n; ++i) {delete[] T[i];}delete[] T;system("pause");return 0;}
今天的分享就到這里了,大家要好好學(xué)C++喲~
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7335瀏覽量
94757 -
C++
+關(guān)注
關(guān)注
22文章
2124瀏覽量
77110
原文標(biāo)題:C++經(jīng)典算法問題:背包問題(迭代+遞歸算法)!含源碼示例
文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學(xué)習(xí)基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
CW32系列MCU在Eclipse GCC + JLink下的使用示例分享
keil實(shí)現(xiàn)c與c++混合編程
C語言與C++的區(qū)別及聯(lián)系
C與C++之間的聯(lián)系
C語言和C++之間的區(qū)別是什么
C/C++條件編譯
C++程序異常的處理機(jī)制
C/C++代碼靜態(tài)測試工具Perforce QAC 2025.3的新特性
技能+1!如何在樹莓派上使用C++控制GPIO?
在OpenVINO? C++代碼中啟用 AddressSanitizer 時(shí)的內(nèi)存泄漏怎么解決?
主流的 MCU 開發(fā)語言為什么是 C 而不是 C++?
C++中的背包問題說明和源碼示例
評論