今天照着崔老師的揹包問題九講學習了多重揹包問題,收穫很大。
在揹包問題九講中,崔老師共給出了三種完全揹包問題的解法,我折中選擇了中間的那種,即“轉化爲01揹包問題”的解法,揹包問題九講上介紹的非常好,很容易理解,在這裏不多說,可遺憾的是文章中沒有給出一個完整的代碼,在這裏貼出,輸入輸出格式以POJ1276爲準:
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
const int VMax=100100,NMax=20000;
int V,N,nn,C[NMax],W[NMax],F[VMax];
int POW2(int a)
{
int ret=1;
while(a--)
ret*=2;
return ret;
}
int main()
{
int tmp1,tmp2,k,f;
while(scanf("%d",&V)!=EOF)
{
memset(F,0,sizeof(F));
nn=0;
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
scanf("%d%d",&tmp1,&tmp2);
k=0;
while(1)
{
if(tmp1-POW2(k+1)+1<=0) break;
++k;
}
for(int j=0;j<k;j++)
{
f=POW2(j);
++nn;
C[nn]=tmp2*f;
W[nn]=tmp2*f;
}
++nn;
f=tmp1-POW2(k)+1;
C[nn]=tmp2*f;
W[nn]=tmp2*f;
}
for(int i=1;i<=nn;i++)
for(int j=V;j>=C[i];j--)
F[j]=max(F[j],F[j-C[i]]+W[i]);
printf("%d\n",F[V]);
}
return 0;
}