多重背包问题,求硬币可以有多少种组合(价值要小于m)
#include<stdio.h> #include<string.h> int dp[100010]; int main() { int i,j,n,m,cont[1001],num[1001],ans,k; while(scanf("%d%d",&n,&m),(n||m)) { for(i=0;i<n;i++) scanf("%d",&cont[i]); for(i=0;i<n;i++) scanf("%d",&num[i]); memset(dp,0,sizeof(dp)); dp[0]=1; for(i=0;i<n;i++) { k=num[i]; if(k*cont[i]>=m) { for(j=cont[i];j<=m;j++) { if(dp[j-cont[i]]==0)continue; dp[j]=1; } } else { ans=1; while(k-ans>0) { for(j=m;j>=ans*cont[i];j--) { if(dp[j-ans*cont[i]]==0)continue; dp[j]=1; } k-=ans;ans=ans*2;//二进制的思想优化多重背包 } if(k>0) for(j=m;j>=k*cont[i];j--) { if(dp[j-k*cont[i]]==0) continue; dp[j]=1; } } } int sum=0; for(i=1;i<=m;i++) { if(dp[i]==1)sum++; } printf("%d\n",sum); } return 0; }