動態規劃0-1揹包問題

0-1揹包問題:ios

有編號分別爲a,b,c,d,e的五件物品,它們的重量分別是2,2,6,5,4,它們的價值分別是6,3,5,4,6,如今給你個承重爲10的揹包,如何讓揹包裏裝入的物品具備最大的價值總和?c++

這個問題用窮舉法固然能夠作,可是用動態規劃所用的時間花銷更少。要用一個二維數組存儲局部最優值,最後達到總的最優值,能夠說是用空間換時間,很是的經典!若是想真正理解動態規劃的思想,就把下面的程序的執行過程在本身的腦海中想一遍,結合程序運行結果圖好好的思考一下,看看運行結果圖裏面的二維數組是如何生成的,雖然會花費一些時間,可是理解後對之後的編程是大有裨益的。編程

直接貼c++代碼:數組

//動態規劃 本程序是自底向上自左向右更新最優值
#include<iostream>
using namespace std;
int main()
{    
    int c=10; //總的承重量,好像沒有用到,由於j也能夠表示
    int m[6][11]={0}; // 第一行與第一列不用,方便編程,表示須要更新的二維數組
    int w[6]={0,2,2,6,5,4}; //多寫個0方便編程,物品的重量
    int v[6]={0,6,3,5,4,6}; //物品的價值
    for(int i=5;i>=1;i--)  //循環五次,動態嘗試放入五個物品
        for(int j=1;j<=10;j++)
            {
                if(i==5) //最後一行不依賴其它行更新最優值,由於表示的是第一個放入揹包的物品
                    {
                        if(w[5]<=j)
                            {m[i][j]=v[5];}
                    }
                else{
                    if(w[i]>j) //動態規劃核心,此式子選擇動態更新局部最優值
                        {
                            m[i][j]=m[i+1][j]; //動態規劃核心,此式子選擇動態更新局部最優值
                        }
                     else
                        {
                            m[i][j] =m[i+1][j]>m[i+1][j-w[i]]+v[i]?m[i+1][j]:m[i+1][j-w[i]]+v[i]; //動態規劃核心,此式子選擇動態更新局部最優值,
                                                        //等價於m[i][j]=max{m[i+1][j],m[i+1][j-w[i]]+v[i]}
} } } cout<<m[1][10]<<endl;//輸出最大價值總和,由於本程序是自底向上自左向右更新最優值,因此最大價值總和在第一行第十列(右上角)。 for(int i=1;i<=5;i++) //循環輸出更新後的二維數組 for(int j=1;j<=10;j++){ cout<<m[i][j]; cout<<" "; if(j==10) cout<<endl; } return 0; }

運行效果圖以及自底向上自左向右更新後的二維數組以下:最大總價值爲15spa

 至此最大價值咱們求出來了是15,還要解決一個問題:有哪些貨物是被選進去了呢?這個問題要用回溯法!就是從程序執行末尾開始code

從運行結果圖可知:m[1][10]=15>m[1+1][10]=11,物品一選中,剩餘重量:15-物品一的重量=10-2=8     blog

         m[2][8]=9>m[3][8]=6,物品二選中,剩餘重量:8-物品二的重量=8-2=6    //注意到沒?m[2][8]中的8就是上一步的剩餘重量io

         m[3][6]=6=m[4][6]=6,物品三沒選中,剩餘重量:仍是6class

         m[4][6]=6=m[5][6]=6,物品四沒選中,剩餘重量:仍是6stream

         m[5][6]!=0,物品五選中 

         綜上:所選物品有物品1,2,5總價值爲15.

相關文章
相關標籤/搜索