問題說明
有N件物品和一個容量為V的背包。
第i件物品的重量是w[i],價值是v[i]。
求解將哪些物品裝入背包可使這些物品的重量總和不超過背包容量,
且價值總和最大。
功能說明
本程序用動態規劃的思想解決了背包問題,并用了兩種算法:迭代法、遞歸法。在迭代法中實現了打印背包問題的表格。
代碼簡述
通過用戶輸入數據,程序輸入檢測,動態分配空間,選擇算法, 用動態規劃的思想求解背包問題。
迭代法:
通過遍歷n行W列,迭代每行每列的值,并把最優解放到 n行(在數組中為第n+1行)W列(在數組中為第W+1列)中。
遞歸法:
通過每次返回前i個物品和承重為j的最優解, 遞歸計算總背包問題的最優解。
源碼示例
using namespace std;
int **T = NULL; // 存儲背包問題表格的數組指針
// 返回兩個值的最大值
int max(int a, int b) {
return (a > b) ? a : b;
}
// 迭代法,能顯示背包問題的表格
int packIterative(int n, int W, int *w, int *v) {
// 循環遍歷n行
for (int i = 1; i <= n; ++i)
{
// 循環遍歷W列
for (int j = 1; j <= W; ++j)
{
//第i個物品能裝下,則比較包括第i個物品和不包括第i個物品,取其最大值
if (w[i] <= j)
T[i][j] = max(v[i] + T[i - 1][j - w[i]], T[i - 1][j]);
// 第i個物品不能裝下,則遞歸裝i-1個
else
T[i][j] = T[i - 1][j];
}
}
return T[n][W];
}
// 遞歸法,不支持顯示背包問題的表格
int packRecursive(int n, int W, int *w, int *v) {
// 結束條件(初始條件),i或者j為0時最大總價值為0
if (n == 0 || W == 0) {
return 0;
}
// 第i個物品不能裝下,則遞歸裝i-1個
if (w[n] > W) {
return packRecursive(n - 1, W, w, v);
}
//第i個物品能裝下,則比較包括第i個物品和不包括第i個物品,取其最大值
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++)
{
// 打印行數
cout << i << ": ";
// 打印W列
for (int w = 0; w <= W; w++)
{
cout << T[i][w] << " ";
}
// 換行
cout << endl;
}
}
int main() {
int *w = NULL; // 存儲每件物品重量的數組指針
int *v = NULL; // 存儲每件物品價值的數組指針
int n; // 物品個數n
int W; // 背包總承重W
cout << "---------------- 背包問題 ----------------" << endl;
cout << "請輸入物品數 n (n>=0) " << endl;
// 輸入背包數
cin >> n;
if (cin.fail() || n < 0)
{
cout << "輸入n錯誤!" << endl;
system("pause");
return 0;
}
cout << "請輸入背包承重量 W (W>=0) " << endl;
// 輸入背包承重量
cin >> W;
if (cin.fail() || W < 0)
{
cout << "輸入W錯誤!" << endl;
system("pause");
return 0;
}
// 分配空間
// 對w和v分配n+1大小
w = new int[n + 1];
v = new int[n + 1];
// 對T分配n+1行,并初始化為0
T = new int *[n + 1]();
// 對T分配W+1列,并初始化為0
for (auto i = 0; i <= n; i++)
{
T[i] = new int[W + 1]();
}
// 輸入背包的重量和價值
for (auto i = 1; i <= n; i++)
{
cout << "請輸入第 " << i << " 個物品的重量和價值(用空格隔開)" << endl;
cin >> w[i] >> v[i];
if (cin.fail() || w[i] < 0 || v[i] < 0)
{
cout << "輸入錯誤!" << 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 << "能裝下物品的最大價值為 " << packIterative(n, W, w, v) << endl;
cout << "------------------------------------------------" << endl;
printT(n, W);
break;
}
case 2:
{
// 遞歸法,不支持顯示背包問題的表格
cout << "能裝下物品的最大價值為 " << packRecursive(n, W, w, v) << endl;
break;
}
default:
{
cout << "輸入錯誤!" << endl;
break;
}
}
cout << "------------------------------------------------" << endl;
delete w;
delete v;
for (int i = 0; i <= n; ++i) {
delete[] T[i];
}
delete[] T;
system("pause");
return 0;
}
今天的分享就到這里了,大家要好好學C++喲~
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
數據
+關注
關注
8文章
6891瀏覽量
88826 -
C++
+關注
關注
22文章
2104瀏覽量
73489
原文標題:C++經典算法問題:背包問題(迭代+遞歸算法)!含源碼示例
文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學習基地】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
基于無操作系統的STM32單片機開發附源碼
到地址空間連續的不同大小的內存空間,且用戶接口簡單,使用方便。 源碼說明 源碼包含memory.h 和 memory.c 兩個文件(嵌入式C
ostream在c++中的用法
ostream 是 C++ 標準庫中一個非常重要的類,它位于 頭文件中(實際上,更常見的是通過包含 頭文件來間接包含 ,因為 包含了 和 )。 ostream 類及其派生類(如 std::cout
如何在FX3 SuperSpeed explorer等電路板上使用openOCD調試C++項目?
在嘗試調試一些可用的 C++ 示例(如 BulkLpAutoCpp)后,我發現任何基于 C++ 的項目在 openocd 下都無法正常調試,反而會停止。 C 項目調試得很好,而且我已經
發表于 05-23 08:16
C/C++中兩種宏實現方式
#ifndef的方式受C/C++語言標準支持。它不僅可以保證同一個文件不會被包含多次,也能保證內容完全相同的兩個文件(或者代碼片段)不會被不小心同時包含。
鴻蒙OS開發實例:【Native C++】
使用DevEco Studio創建一個Native C++應用。應用采用Native C++模板,實現使用NAPI調用C標準庫的功能。使用C標準庫hypot接口計算兩個給定數平方和的平
使用 MISRA C++:2023? 避免基于范圍的 for 循環中的錯誤
在前兩篇博客中,我們?向您介紹了新的 MISRA C++ 標準?和?C++ 的歷史?。在這篇博客中,我們將仔細研究以 C++
c語言,c++,java,python區別
C語言、C++、Java和Python是四種常見的編程語言,各有優點和特點。 C語言: C語言是一種面向過程的編程語言。它具有底層的特性,能夠對計算機硬件進行直接操作。
c++怎么開始編程
C++是一種高級的、通用的編程語言,用于開發各種類型的應用程序。它是從C語言演變而來,也是一種靜態類型語言,可以在不同的平臺上進行開發。C++具有高度的靈活性和性能,并且廣泛應用于游戲開發、桌面
評論