知识点:多重背包
多重背包由01背包和完全背包构成,有了01和完全的基础,多重还是挺好理解的。
#include <cstdio>
#include <memory.h>
bool dp[100001];
int V;
void ZeroPack(int val)
{
for(int v=V;v>=val;v--)
if(dp[v-val]) dp[v]=1;
}
void CompletePack(int val)
{
for(int v=val;v<=V;v++)
if(dp[v-val]) dp[v]=1;
}
void MultiplePack(int val,int num)
{
int cnt;
if(val*num>=V) CompletePack(val);
else
{
cnt=1;
while(cnt<num)
{
ZeroPack(val*cnt);
num-=cnt;
cnt+=cnt;
}
}
ZeroPack(val*num);
}
bool scan_d(int &n) //整数输入外挂,减少时间
{
char i;
bool I=0;
i=getchar();
if(i==EOF) return 0;
while(i!='-'&&(i<'0'||i>'9'))
i=getchar();
if(i=='-') I=1,n=0;
else n=i-'0';
while(i=getchar(),i>='0'&&i<='9')
n=n*10+i-'0';
if(I) n=-n;
return 1;
}
int main()
{
int n;
while(scan_d(n),scan_d(V),n&&V)
{
int val[n],num[n];
for(int i=0;i<n;i++)
scan_d(val[i]);
for(int i=0;i<n;i++)
scan_d(num[i]);
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=0;i<n;i++)
MultiplePack(val[i],num[i]);
int cnt=0;
for(int i=1;i<=V;i++)
if(dp[i]) cnt++;
printf("%d\n",cnt);
}
return 0;
}
![](http://hi.csdn.net/attachment/201111/10/0_1320893751G5BJ.gif)
![](http://hi.csdn.net/attachment/201111/10/0_1320893767f6kJ.gif)