1.背包問題[窮舉法]


有一個背包最多可裝重量8千克的物品,假設要用該背包裝如下水果,要求使背包中裝的物品的價值最大,應該裝下列哪些物品才能達到要求?

物品 重量 價值
蘋果 5千克 40元
2千克 12元
桃子 1千克 7元
葡萄 1千克 8元
香蕉 6千克 48元

解題思路:首先窮舉所有組合可能,有5種物品,一共組合32-1種可能。然后排除超重的可能,在不大於8千克的前提下,再計算各種可能的總價值,最后,比較這些組合的價值,得到最大值。這種思路還是比較簡單清晰的。

二進制模擬的概念:對於每個物品,在生成的組合中有兩種可能:一是加入背包,二是排除在背包之外,這類有多種物品,每個物品有兩種可能的情況,可以使用二進制數來進行模擬。對於n個物品,就可用n位二進制模擬。位為1,表示對應物品加入背包,位為0,表示對應物品不在背包中。

int binadd(char select1[],int n) /*二進制模擬運算*/ 
{
    int i,carry=0;
    select1[0] += 1;
    for (i = 0; i < n; i++)
    {
        select1[i] += carry; //加上進位
        carry = select1[i] /2;//計算進位         
        select1[i] %= 2; //保留0或1?
        if (carry==0)
            return 0;
    }
    return carry;
}

流程

/*-------完整代碼@映雪---------*/
/*初始化一組數據,省略用堆的繁瑣,簡化流程*/
 
#include <iostream>
using namespace std;
typedef struct
{
    int value[5];
    int weight[5];
    int num;
    int limitw;
}Goods;
int bin(int s[],int n) /*二進制模擬運算*/ 
{
    int i,carry=0;
    s[0] += 1;
    for (i = 0; i < n; i++)
    {
        s[i] += carry; //加上進位
        carry = s[i] /2;//計算進位         
        s[i] %= 2; //保留0或1?
        if (carry==0)
            return 0;
    }
    return carry;
}
void backpack(Goods *g,int select[])/*計算主程序*/
{
   int i,flag;
   int S[5];/*臨時狀態數組*/
   double maxvalue = 0,tw,tv;
   for (i = 0; i < g->num; i++)//將數組清空 
       S[i] = 0;
           
   while(bin(S, g->num) == 0) //進行一次二進制模擬運算 
   {
       tw = 0;/*臨時重量*/
       tv = 0;/*臨時價值*/
       flag = 1;
       for (i = 0; i < g->num; i++) //根據選中狀態進行試算 
       {
           if (S[i] == 1) //若選中該物品
           {
               tw += g->weight[i]; //累加選中物品的重量 
               tv += g->value[i];//累加選中物品的價值 
               if (tw > g->limitw) //超重
               {
                   flag = 0;
                   break; //退出本次方案的試算 
               }
           } 
       }
       if(flag && maxvalue < tv) //若方案選中物品重量未超過限制,並且本方案累加價值大於已有方案的最大價值
       {
           maxvalue = tv;
           for(i = 0; i < g->num; i++) //保存方案(也是更新方案)
               select[i] = S[i];
       } 
   }   
}
int main()
{
      int sumweight,maxvalue; //用來保存階段最優價值 
       int select[5];
       Goods g={{40,12,7,8,48},{5,2,1,1,6},5,8};/*初始化一組數據*/
       backpack(&g,select);
       sumweight=0;
       maxvalue=0; 
       printf("可將以下物品裝入背包,價值最大:\n");
       for (int i = 0; i < g.num; ++i)
         if (select[i])
         {
           printf("第%d號物品,重量:%d千克,價值:%d元\n", i + 1, g.weight[i], g.value[i]);
           sumweight+=g.weight[i];
           maxvalue+=g.value[i];
         }     
       printf("\n總重量為:%d千克,總價值為:%d元\n", sumweight, maxvalue ); 
      return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM