01背包 n代表物品种数,c[]代表花费,val[]代表价值 num[]代表 数量 for(i=1;i<=n;i++) { for(j=v;j>=c[i];j--) dp[j]=max(dp[j],dp[j-c[i]]+val[i]); } 多重背包 for(i=1;i<=m;i++) { for(j=1;j<=num[i];j++) { for(k=n;k>=w[i];k--) dp[k]=max(dp[k],dp[k-w[i]]+val[i]); } }
第二种
1 for( i = ;i<= m; ++i) 2 { 3 for( j = V ;j >= v[i]; --j) 4 { 5 for( k = 0; k <= num[i] ;k++) 6 { 7 vsum = k*val[i]; 8 wsum = k*v[i]; 9 if( wsum > V) break; 10 else 11 { 12 f[i] = max(f[i],f[ i - wsum] + vsum); 13 } 14 } 15 } 16 }
完全背包 for(i=1;i<=n;i++) { for(j=c[i];j<=v;j++) dp[j]=max(dp[j],dp[j-c[i]]+val[i]); }
多重背包的二进制优化
http://poj.org/problem?id=1276 #include<iostream> #include<stdio.h> #include<string.h> const int N=120005; using namespace std; int v,n,num[N],val[N],dp[N]; void zeropack(int c) { for(int i=v;i>=c;i--) dp[i]=max(dp[i],dp[i-c]+c); } void completepack(int c) { for(int i=c;i<=v;i++) dp[i]=max(dp[i],dp[i-c]+c); } void multipack(int c,int num) { if(c*num>=v) completepack(c); else { int k=1; while(k<num) { zeropack(k*c); num-=k; k*=2; } zeropack(num*c); } } int main() { int i; while(scanf("%d%d",&v,&n)!=EOF) { int flag=0; memset(dp,0,sizeof(dp)); for(i=0;i<n;i++) { scanf("%d%d",&num[i],&val[i]); if(val[i]==v){dp[v]=v;flag=1;} } if(v==0){dp[v]=0;flag=1;} if(!flag) { for(i=0;i<n;i++) { if(num[i]&&val[i]<=v)multipack(val[i],num[i]); } } printf("%d\n",dp[v]); } }