0-1背包問題

摘抄:http://www.cnblogs.com/Anker/archive/2013/05/04/3059070.html

1. 0-1背包問題描述

有一個竊賊在偷竊一家商店時發(fā)現(xiàn)有n件物品,第i件物品價值為vi元,重量為wi,假設(shè)vi和wi都為整數(shù)。他希望帶走的東西越值錢越好,但他的背包中之多只能裝下W磅的東西,W為一整數(shù)。他應(yīng)該帶走哪幾樣?xùn)|西?

0-1背包問題中:每件物品或被帶走,或被留下,(需要做出0-1選擇)。小偷不能只帶走某個物品的一部分或帶走兩次以上同一個物品。

    wi  vi  
a   2   6   
b   2   3   
c   6   5   
d   5   4   
e   4   6   
w       1   2   3   4   5   6   7   8   9   10
a       0   6   6   9   9   12  12  15  15  15
b       0   3   3   6   6   9   9   9   10  11
c       0   0   0   6   6   6   6   6   10  11
d       0   0   0   6   6   6   6   6   10  10
e       0   0   0   6   6   6   6   6   6   6

這張表是至底向上,從左到右生成的。(a,b,c,d,e五件商品,最多能裝10磅的東西,w行表重量,其他行的數(shù)字表max價值)

2. 0-1背包問題子結(jié)構(gòu):

選擇一個給定物品i,則需要比較選擇i的形成的子問題的最優(yōu)解與不選擇i的子問題的最優(yōu)解。分成兩個子問題,進(jìn)行選擇比較,選擇最優(yōu)的。

0-1背包問題遞歸過程:設(shè)有n個物品,背包的重量為w,C[i][w]為最優(yōu)解。即:

3. 偽代碼:

4. 編程實(shí)現(xiàn)

#include <iostream>
using namespace std;

//物品數(shù)據(jù)結(jié)構(gòu)
typedef struct commodity
{
    int value;  //價值
    int weight; //重量
}commodity;

const int N = 3;  //物品個數(shù)
const int W = 50; //背包的容量

//初始物品信息
commodity goods[N+1]={{0,0},{60,10},{100,20},{120,30}};
int select[N+1][W+1];

int max_value();

int main()
{
    int maxvalue = max_value();
    cout<<"The max value is: ";
    cout<<maxvalue<<endl;
    int remainspace = W;
    //輸出所選擇的物品列表:
    for(int i=N; i>=1; i--)
    {
        if (remainspace >= goods[i].weight)
        {
             if ((select[i][remainspace]-select[i-1][remainspace-goods[i].weight]==goods[i].value))
             {
                 cout << "item " << i << " is selected!" << endl;
                 remainspace = remainspace - goods[i].weight;//如果第i個物品被選擇,那么背包剩余容量將減去第i個物品的重量 ;
             }
        }
    }
    return 0;
}
int max_value()
{
    //初始沒有物品時候,背包的價值為0
    for(int w=1;w<=W;++w)
        select[0][w] = 0;
    for(int i=1;i<=N;++i)
    {
        select[i][0] = 0;  //背包容量為0時,最大價值為0
           for(int w=1;w<=W;++w)
           {
               if(goods[i].weight <= w)  //當(dāng)前物品i的重量小于等于w,進(jìn)行選擇
               {
                   if( (goods[i].value + select[i-1][w-goods[i].weight]) > select[i-1][w])
                    select[i][w] = goods[i].value + select[i-1][w-goods[i].weight];
                   else
                    select[i][w] = select[i-1][w];
               }
               else //當(dāng)前物品i的重量大于w,不選擇
                 select[i][w] = select[i-1][w];
           }
    }
    return select[N][W];  //最終求得最大值
}

5. 測試結(jié)果

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容