日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

01背包问题的动态规划求解及其C++实现

發布時間:2023/12/29 c/c++ 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 01背包问题的动态规划求解及其C++实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文講解01背包問題的動態規劃求解,并使用C++進行了實現

文章目錄

  • 01背包問題
  • 動態規劃
  • 01背包問題的動態規劃求解
  • 01背包問題的動態規劃求解-C++實現

01背包問題

nnn個物品,這些物品的重量分別為w1,w2,...,wnw_1,w_2,...,w_nw1?,w2?,...,wn?,價值分別為v1,v2,...,vnv_1,v_2,...,v_nv1?,v2?,...,vn?.

現給定一個背包,背包的容量為CCC,要求從這個nnn個物品中選擇一些物品裝進背包,讓背包盡可能裝滿,并使得背包里裝的物品的價值最大。

要從這些物品中挑選一些裝進背包,對于某一物品而言,只有裝和不裝兩種選擇,因此稱為01背包問題

動態規劃

動態規劃是一種算法設計技術,它用來解決類似這樣的問題:

一個問題可以被分成很多個階段,而且任何一階段的行為都依賴于該階段前面的狀態,但是該階段前面的狀態是如何得來的與該階段無關。我們稱這樣的過程為多階段決策過程。

事實上,動態規劃就是解決多段決策過程最優問題的一種方法

在使用動態規劃法求解問題時,被求解的問題應滿足最優性原則

一個最優問題的任何實例的最優解是由該實例的子實例的最優解組成的(子問題最優,全局才能最優)

拿斐波那契數列來說

  • 如果我們直接使用遞歸表達式求解的話回耗費很大內存且會被重復計算
  • 而如果我們正向計算,把每一次計算的結果保存起來,則只需要進行加法運算,則大大地方便了計算

因此,對于交疊子問題的求解,我們也可以使用這種方式:

對交疊子問題的每個較小子問題求解一次后記錄在表中,就可以從表中得到原始問題的解

01背包問題的動態規劃求解

我們這里舉例說明背包問題的動態規劃求解

背包容量為5,各種物品的重量及價值如下:

物品重量價值
1212
2110
3320
4215

正如前面我們所分析的,我們通過填表的方式利用動態規劃的方式求解的話能夠大大地簡化問題的求解:

我們用V(i,j)V(i,j)V(i,j)表示將前i個物品放到容量為j的背包中時最優解的物品總價值,則在裝入物品的時候我們有兩種情況:

  • 第i個物品不能被放入背包,則背包的價值為原先沒有裝入第i個物品時的價值:
    V(i,j)=V(i?1,j)V(i,j) = V(i - 1,j)V(i,j)=V(i?1,j)
  • 可將物品放入背包,應對放入物品放入背包后的情況進行評估,如果放入后背包的價值增加,則放入,否則不放入,價值為原來的沒有放入時的價值:
    V(i,j)=max{V(i?1,j),vi+V(i?1,j?wi)}V(i,j) = max\{ V(i - 1,j),{v_i} + V(i - 1,j - {w_i})\} V(i,j)=max{V(i?1,j),vi?+V(i?1,j?wi?)}
  • 即:

    我們對背包容量為0到5填表,得到表的情況如下:

    重量價值iii\ jjj012345
    0000000
    21210012121212
    110201012222222
    320301012223032
    215401015253037

    最終的最優解為表的后一個元素37

    01背包問題的動態規劃求解-C++實現

    #include <iostream> using namespace std; int knapsack(int num,int capacity,int weight[],int value[]){//使用動態規劃求解0-1背包問題/*@parameters:@num:物品數量,整數類型@capacity:背包容量,整數類型@weight:各個物品的重量,數組類型@value:各個物品的價值,數組類型*/int space,sub_cap,total_value[num+1][capacity+1];for(int i=0;i<=num;i++)for(int j=0;j<=capacity;j++)total_value[i][j]=0;//初始化記憶表格for(sub_cap=1;sub_cap<=capacity;sub_cap++){for(space=1;space<=num;space++){if(sub_cap>=weight[space-1]){//判斷是否能不能裝下//能裝下,判斷裝了以后是不是背包的價值更大了total_value[space][sub_cap]=max(total_value[space-1][sub_cap],total_value[space-1][sub_cap-weight[space-1]]+value[space-1]);}else{//裝不下的話背包價值還是沒有裝之前的價值total_value[space][sub_cap]=total_value[space-1][sub_cap];}}}return total_value[num][capacity]; } int main(){int num=4,capacity=5,weight[]={2,1,3,2},value[]={12,10,20,15};cout<<knapsack(num,capacity,weight,value);return 0; }

    代碼的運行結果為:

    37

    才疏學淺,難免有錯誤和不當之處,歡迎交流批評指正!
    同時有問題的話歡迎留言或郵箱聯系(ljt_IT@163.com)。

    創作不易,覺得寫得不錯就微信掃碼獎勵一下吧!

    總結

    以上是生活随笔為你收集整理的01背包问题的动态规划求解及其C++实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。