今天照着崔老师的背包问题九讲学习了多重背包问题,收获很大。
在背包问题九讲中,崔老师共给出了三种完全背包问题的解法,我折中选择了中间的那种,即“转化为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;
}