簡單的方法來自http://poj.org/showmessage?message_id=156697
#include<stdio.h>#include<string.h>int dp[100010];int num[110],v[110];int used[100010];int main(){int n,m,i,j;while(scanf("%d%d",&n,&m),(n||m)){for(i=0;i<n;i++) scanf("%d",&v[i]);for(i=0;i<n;i++) scanf("%d",&num[i]);memset(dp,0,sizeof(dp));dp[0]=1;int ans=0;for(i=0;i<n;i++){ memset(used,0,sizeof(used)); for(j=v[i];j<=m;j++){ if(!dp[j]&&dp[j-v[i]]&&used[j-v[i]]<num[i]){ ans++; dp[j]=1; used[j]=used[j-v[i]]+1; } }}printf("%d\n",ans);} return 0;}
多重背包倍增
#include<cstdio>using namespace std;const int mm=111111;const int mn=111;int a[mn],c[mn];bool f[mm];int n,m;void CompletePack(int v){ for(int i=v;i<=m;++i)f[i]|=f[i-v];}void ZeroOnePack(int v){ for(int i=m;i>=v;--i)f[i]|=f[i-v];}int main(){ int i,j,ans; while(scanf("%d%d",&n,&m),n+m) { for(i=0;i<n;++i)scanf("%d",&a[i]); for(i=0;i<n;++i)scanf("%d",&c[i]); for(i=f[0]=1;i<=m;++i)f[i]=0; for(i=0;i<n;++i) if(c[i]) if(c[i]*a[i]>=m)CompletePack(a[i]); else { j=1; while(j<c[i]) { ZeroOnePack(a[i]*j); c[i]-=j; j<<=1; } ZeroOnePack(a[i]*c[i]); } ans=0; for(i=1;i<=m;++i)ans+=f[i]; printf("%d\n",ans); } return 0;}