点击打开链接http://acm.hdu.edu.cn/showproblem.php?pid=2844
/*多重背包;题意:第一行硬币种数n和最大价值的手表价值m, 第二行n种硬币的面值value和数量number;求这些硬币可以买 多少种不同价值的手表,手表价值1——m; 思路:最简单的多重背包,dp[0]=1,然后将能买到手表价值j, dp[j]置为1,最后求和; */ #include<stdio.h> #include<string.h> int dp[100005],value[100005],number[1005]; void ZeroOnePack(int cost,int w) { int i; dp[0]=1; for(i=w;i>=cost;i--) if(dp[i-cost]) dp[i]=1; } void CompletePack(int cost,int w) { int i; dp[0]=1; for(i=cost;i<=w;i++) if(dp[i-cost]) dp[i]=1; } void MultiplePack(int cost,int n,int w) { int i,k=1; if(n*cost>=w) CompletePack(cost,w); while(k<n){ ZeroOnePack(k*cost,w); n-=k; k<<=1; } ZeroOnePack(n*cost,w); } int main() { int n,m; while(scanf("%d%d",&n,&m),n!=0&&m!=0){ int i,j,s=0; for(i=0;i<n;i++) scanf("%d",&value[i]); for(i=0;i<n;i++) scanf("%d",&number[i]); memset(dp,0,sizeof(dp)); for(i=0;i<n;i++){ MultiplePack(value[i],number[i],m); } for(i=1;i<=m;i++) if(dp[i]) s++; printf("%d\n",s); } return 0; }