背包问题代码
#include <iostream>using namespace std;int f[1000];
const int N = 5;//物品的種類
int volume[N];//每種物品所占有的空間
int val[N];//每種物品的價值
int maxVol;void MultiplePack(int volm,int val,int count)//第i種物品的數(shù)量為count;
{if(volm * count >=maxVol){CompletePack(volm,val);return;}int k = 1;while (k<count)//將count個的第i物品分成n份,每份的數(shù)量按照1,2^1,2^2,2^3,...,count - 2^i +1,如此將每份都看成不同的物品,份數(shù)相加能表示任何小于等于count的整數(shù){ZeroOnePack(k*volm,k*val);count = count - k;k = 2*k;}ZeroOnePack(count*volm,count*val);
}
void ZeroOnePack(int volm,int val)//設此次處理的是第i中物品,則此函數(shù)求出的是在每種容量下,從第0到第i種物品的最優(yōu)組合,使其價值最高(已知從第0到第i-1的最優(yōu)組合,此函數(shù)的作用只是對每一種容量下判斷是否添加第i中物品)
{for (int v = maxVol;v>=volm;--v){f[v] = max(f[v],f[v-volm] + val);//max括號里面的f都是指在從第0到第i-1種物品最優(yōu)組合。當處理第一個物品時,因為f被初始化為0,所以這一步也等價于初始化f,即在小于等于maxVol的情況下,最大值都是第一個物品的價值}
}
void CompletePack(int volm,int val)//不管在v-volm容量下是否已經添加第i種物品了,這個函數(shù)只需判斷是v-volm容量下添加第i種物品的價值和在v容量下從第0到第i-1物品的價值
{for (int v=volm;v<=maxVol;++v){f[v] = max(f[v],f[v-volm] + val);}
}int main()
{memset(f,0,sizeof(f));for (int i = 0;i<N;++i){ZeroOnePack(volume[i],val[i]);}return 0;
}
總結