完全背包问题 有n种重量和价值分别为wi,vi的物品,从这些物品中挑选出总重量不超过W的物品,求挑选出的物品总价值的最大值。每件物品物品可以挑选任意多件。 1《=n《=100 1《=wi,vi<=100 1<=W《=10000 样例: n=3 w: 3,4,2 v:4,5,3 W=7
dp[i][j]:从前i种物品中挑选总重量不超过j的总价值的最大值
dp[0][j]=0;
dp[i+1][j]={
max(dp[i][j-k*w[i]]+k*v[i],dp[i+1][j])
}
由此,我们可以得到一个递推程序:
int dp[MAX_N+1][MAX_M+1];//dp数组 void solve(){ for(int i=0;i<n;i++) { for(int j=0;j<W;j++){ for(int k=0;k*w[i]<=j;k++){ dp[i+1][j]=max(dp[i][j],dp[i+1][j-k*w[i]]+v[i]*k); } } } }
其实,dp[i][j]=dp[i-1][j-w[i]]+v[i],这样可以压缩掉一维。
压缩之后:
for(int i=0;i<n;i++){ for(int j=0;j<=W;j++){ if(j>w[i]){ dp[i+1][j]=max(dp[i+1][j],dp[i][j-w[i]+v[i]]); } } }