http://www.cnblogs.com/Kalix/p/7617856.html 01背包问题
https://www.cnblogs.com/Kalix/p/7622102.html 完全背包问题
https://blog.csdn.net/mystery_guest/article/details/51878140 多重背包二进制优化
01背包
二维版
for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(weight[i]<=j) dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);//能放下拿或者不拿 else dp[i][j]=dp[i-1][j]; } }
一维版
for(int i=1;i<=n;i++) { for(int j=m;j>=weight[i];j--) dp[j]=max(dp[j],dp[j-weight[i]]+value[i]); }
完全背包
二维版
for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(weight[i]<=j) dp[i][j]=max(dp[i-1][j],dp[i][j-weight[i]]+value[i]);//能放下拿或者不拿 else dp[i][j]=dp[i-1][j]; } }
一维版
for(int i=1;i<=n;i++) { for(int j=weight[i];j<=m;j++) dp[j]=max(dp[j],dp[j-weight[i]]+value[i]); }
多重背包+二进制优化
#include<stdio.h> #include<string.h> #include<stdlib.h> #define N 1000 //物品个数 #define M 100000000 //所有物品可能的最大价值 int m[N],c[N],w[N],f[M]; int V; int max(int a,int b){return a>b?a:b;} void ZeroOnePack(int cost,int weight) { int v; for(v=V;v>=cost;v--) f[v]=max(f[v],f[v-cost]+weight); } void CompletePack(int cost,int weight) { int v; for(v=cost;v<=V;v++) f[v]=max(f[v],f[v-cost]+weight); } void MultiplePack(int cost,int weight,int amount) { int k; if(cost*amount>=V) { CompletePack(cost,weight); return; } k=1; while(k<amount) { ZeroOnePack(k*cost,k*weight); amount=amount-k; k=k*2; } ZeroOnePack(amount*cost,amount*weight); } int main() { int n,i; scanf("%d %d",&n,&V); for(i=0;i<n;i++) scanf("%d %d %d",m+i,c+i,w+i); for(i=0;i<n;i++) MultiplePack(c[i],w[i],m[i]); printf("%d ",f[V]);return 0; }