C++解決背包問題(Knapsacks Problem)
總的來說,背包問題是一種動態優化問題。
背包載重量一定,給定一組物品,沒件物品有自己的價值和重量,問題要求在不超過背包載重前題下,怎樣讓載入的物品價值和最大?假如有物品如下:
物品號 物品名 重量 價錢
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>