C++解決背包問題(Knapsacks Problem)

kdloeki 9年前發布 | 1K 次閱讀 C/C++

總的來說,背包問題是一種動態優化問題。
背包載重量一定,給定一組物品,沒件物品有自己的價值和重量,問題要求在不超過背包載重前題下,怎樣讓載入的物品價值和最大?假如有物品如下:
       物品號           物品名               重量             價錢
          0                     李子                4                   4500
          1                     蘋果                5                   5700
          2                     橘子                2                   2250
          3                     草莓                1                   1100
          4                     甜瓜                6                   6700
 
      解決問題要用到動態規劃(Dynamic programming),從空集合開始,每增加一個元素就先求出該階段的最優解,知道所有的元素加入到集合中,最后就可以得到最優解。其實是求出了在每個重量單位的最優解,是一個最優解數列。
      代碼中value代表目前最優解所得的總和,item表示最后一個放入背包的水果。
     我們可以這樣想,把問題逆過來考慮,假設最后放入的是2#,則之前背包只能放下(8-2)的重量了,后二個放入的是蘋果,則之前只能放入(8-2-5)的重量了,以此類推,只考慮他的每個載重量的最優解,以每個物品為單位以此加入,得到最優解數列。

#include<stdio.h>

include<stdlib.h>

define LIMIT 8

define N 5

define MIN 1

struct body{ char name[20]; int size; int price; };

typedef struct body object;

int main(void){ int item[LIMIT+1] ={0}; int value[LIMIT+1] = {0}; int newvalue,i,s,p;

object a[] = {{"李子",4,4500},
{"蘋果",5,5700},
{"橘子",2,2250},
{"草莓",1,1100},
{"甜瓜",6,6700}};

for(i = 0;i<N;i++){
    for(s=a[i].size;s<=LIMIT;s++){
        p=s-a[i].size;
        newvalue = value[p]+a[i].price;
        if(newvalue>value[s]){
            value[s] = newvalue;
            item[s] = i;
        }
    }
}
printf("物品\t價格\n");
for(i=LIMIT;i>=MIN;i=i-a[item[i]].size){
    printf("%s\t%d\n",a[item[i]].name,a[item[i]].price);
}

printf("合計\t%d\n",value[LIMIT]);
return 0;

}</pre>

 本文由用戶 kdloeki 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!