0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C++中的背包問題說明和源碼示例

C語言編程學(xué)習(xí)基地 ? 來源:C語言編程學(xué)習(xí)基地 ? 作者:C語言編程學(xué)習(xí)基地 ? 2021-10-12 09:27 ? 次閱讀

問題說明

有N件物品和一個容量為V的背包。

第i件物品的重量是w[i],價值是v[i]。

求解將哪些物品裝入背包可使這些物品的重量總和不超過背包容量,

且價值總和最大。

功能說明

本程序用動態(tài)規(guī)劃的思想解決了背包問題,并用了兩種算法:迭代法、遞歸法。在迭代法中實現(xiàn)了打印背包問題的表格。

代碼簡述

通過用戶輸入數(shù)據(jù),程序輸入檢測,動態(tài)分配空間,選擇算法, 用動態(tài)規(guī)劃的思想求解背包問題。

迭代法:

通過遍歷n行W列,迭代每行每列的值,并把最優(yōu)解放到 n行(在數(shù)組中為第n+1行)W列(在數(shù)組中為第W+1列)中。

遞歸法:

通過每次返回前i個物品和承重為j的最優(yōu)解, 遞歸計算總背包問題的最優(yōu)解。

源碼示例

#include #include using namespace std;
int **T = NULL;    // 存儲背包問題表格的數(shù)組指針
// 返回兩個值的最大值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個物品能裝下,則比較包括第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) {  // 結(jié)束條件(初始條件),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++)  {    // 打印行數(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;    // 存儲每件物品價值的數(shù)組指針  int n;        // 物品個數(shù)n  int W;        // 背包總承重W
  cout << "---------------- 背包問題 ----------------" << endl;  cout << "請輸入物品數(shù) n (n>=0) " << endl;
  // 輸入背包數(shù)  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;}

今天的分享就到這里了,大家要好好學(xué)C++喲~

責(zé)任編輯:haq
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    6715

    瀏覽量

    88308
  • C++
    C++
    +關(guān)注

    關(guān)注

    21

    文章

    2085

    瀏覽量

    73302

原文標(biāo)題:C++經(jīng)典算法問題:背包問題(迭代+遞歸算法)!含源碼示例

文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學(xué)習(xí)基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    ostream在c++的用法

    ostream 是 C++ 標(biāo)準(zhǔn)庫中一個非常重要的類,它位于 頭文件(實際上,更常見的是通過包含 頭文件來間接包含 ,因為 包含了 和 )。 ostream 類及其派生類(如 std::cout
    的頭像 發(fā)表于 09-20 15:11 ?93次閱讀

    C++語言基礎(chǔ)知識

    電子發(fā)燒友網(wǎng)站提供《C++語言基礎(chǔ)知識.pdf》資料免費下載
    發(fā)表于 07-19 10:58 ?6次下載

    C++實現(xiàn)類似instanceof的方法

    函數(shù),可實際上C++沒有。但是別著急,其實C++中有兩種簡單的方法可以實現(xiàn)類似Java的instanceof的功能。 在 C++
    的頭像 發(fā)表于 07-18 10:16 ?355次閱讀
    <b class='flag-5'>C++</b><b class='flag-5'>中</b>實現(xiàn)類似instanceof的方法

    數(shù)字濾波器是如何工作的

    之前我們在說明數(shù)字濾波器的時候,多為Python來進(jìn)行示例驗證的。實際應(yīng)用,多為C/C++,無論是在嵌入式系統(tǒng)
    的頭像 發(fā)表于 06-13 10:09 ?365次閱讀
    數(shù)字濾波器是如何工作的

    如何在FX3 SuperSpeed explorer等電路板上使用openOCD調(diào)試C++項目?

    在嘗試調(diào)試一些可用的 C++ 示例(如 BulkLpAutoCpp)后,我發(fā)現(xiàn)任何基于 C++ 的項目在 openocd 下都無法正常調(diào)試,反而會停止。 C 項目調(diào)試得很好,而且我已經(jīng)
    發(fā)表于 05-23 08:16

    C/C++兩種宏實現(xiàn)方式

    #ifndef的方式受C/C++語言標(biāo)準(zhǔn)支持。它不僅可以保證同一個文件不會被包含多次,也能保證內(nèi)容完全相同的兩個文件(或者代碼片段)不會被不小心同時包含。
    的頭像 發(fā)表于 04-19 11:50 ?432次閱讀

    鴻蒙OS開發(fā)實例:【Native C++

    使用DevEco Studio創(chuàng)建一個Native C++應(yīng)用。應(yīng)用采用Native C++模板,實現(xiàn)使用NAPI調(diào)用C標(biāo)準(zhǔn)庫的功能。使用C標(biāo)準(zhǔn)庫hypot接口計算兩個給定數(shù)平方和的平
    的頭像 發(fā)表于 04-14 11:43 ?2163次閱讀
    鴻蒙OS開發(fā)實例:【Native <b class='flag-5'>C++</b>】

    使用 MISRA C++:2023? 避免基于范圍的 for 循環(huán)中的錯誤

    在前兩篇博客,我們?向您介紹了新的 MISRA C++ 標(biāo)準(zhǔn)?和?C++ 的歷史?。在這篇博客,我們將仔細(xì)研究以 C++
    的頭像 發(fā)表于 03-28 13:53 ?516次閱讀
    使用 MISRA <b class='flag-5'>C++</b>:2023? 避免基于范圍的 for 循環(huán)中的錯誤

    c語言,c++,java,python區(qū)別

    C語言、C++、Java和Python是四種常見的編程語言,各有優(yōu)點和特點。 C語言: C語言是一種面向過程的編程語言。它具有底層的特性,能夠?qū)τ嬎銠C(jī)硬件進(jìn)行直接操作。
    的頭像 發(fā)表于 02-05 14:11 ?1364次閱讀

    C++簡史:C++是如何開始的

    的 MISRA C++:2023 博客系列的第二部分。 在這篇博客,我們將深入探討 C++ 的歷史、編程語言多年來的發(fā)展歷程以及它的下一步發(fā)展方向。
    的頭像 發(fā)表于 01-11 09:00 ?427次閱讀
    <b class='flag-5'>C++</b>簡史:<b class='flag-5'>C++</b>是如何開始的

    C語言和C++那些不同的地方

    ++11標(biāo)準(zhǔn)。根據(jù)不同的標(biāo)準(zhǔn),它們的功能也會有所不同,但是越新的版本支持的編譯器越少,所以本文在討論的時候使用的C語言標(biāo)準(zhǔn)是C89,C++標(biāo)準(zhǔn)是C++99.我們來介紹
    的頭像 發(fā)表于 12-07 14:29 ?773次閱讀
    <b class='flag-5'>C</b>語言和<b class='flag-5'>C++</b><b class='flag-5'>中</b>那些不同的地方

    如何選擇創(chuàng)建c語言和c++

    選擇創(chuàng)建 C 語言和 C++ 都需要綜合考慮多個因素。在決定使用哪種語言之前,我們需要對這兩種語言的特點、優(yōu)缺點、適用場景、學(xué)習(xí)成本等進(jìn)行全面的了解和對比。下面是關(guān)于選擇創(chuàng)建 C 語言和 C+
    的頭像 發(fā)表于 11-27 15:58 ?455次閱讀

    c++怎么開始編程

    C++是一種高級的、通用的編程語言,用于開發(fā)各種類型的應(yīng)用程序。它是從C語言演變而來,也是一種靜態(tài)類型語言,可以在不同的平臺上進(jìn)行開發(fā)。C++具有高度的靈活性和性能,并且廣泛應(yīng)用于游戲開發(fā)、桌面
    的頭像 發(fā)表于 11-27 15:56 ?734次閱讀

    c++多行注釋快捷鍵

    C++,多行注釋(也稱為塊注釋)是一種用于注釋大段代碼或多個語句的方法。當(dāng)你希望暫時禁用一些代碼或者解釋特定部分代碼的作用時,多行注釋是非常有用的。 在C++,多行注釋以 /*
    的頭像 發(fā)表于 11-22 10:24 ?6779次閱讀

    C++之父新作帶你勾勒現(xiàn)代C++地圖

    為了幫助大家解決這些痛點問題,讓大家領(lǐng)略現(xiàn)代C++之美,掌握其中的精髓,更好地使用C++,C++之父Bjarne Stroustrup坐不住了,他親自操刀寫就了這本《C++之旅》!
    的頭像 發(fā)表于 10-30 16:35 ?696次閱讀
    <b class='flag-5'>C++</b>之父新作帶你勾勒現(xiàn)代<b class='flag-5'>C++</b>地圖