1.0-1 背包问题
一个背包有一定的承重,有N件物品,每件都有自己的价值,记录在数组v中,也有自己的重量记录在数组w中,要求不超过背包承重前提下,选出物品最大的价值量。
//0-1背包问题,要么选择,要不不选择,只有一个
public class maxValue {
//dp[x][y]表示前X件物品,不超过重量Y时候的最大价值。枚举第X件物品的情况:
//如果选择第X件物品,则前X-1件物品得到的重量不能超过y-W[x]
//如果不选择第x件物品,则前x-1件物品的重量不能超过y
//dp[x][y]=max[dp[x-1][y],dp[x-1][y-w[x]]+v[x]]
int maxValue1(int[] w,int[] v,int n,int cap){
int[][] dp = new int[n][cap+1];
for(int i=0;i<n;i++)
dp[i][0]=0;
for(int i=0;i<cap+1;i++){
if(i>=w[0])//cap 大小大于weight,则可以转入产生价值
dp[0][i]=v[0];
else
dp[0][i]=0;
}
for(int i=1;i<n;i++)
for(int j=1;j<cap+1;j++){
if(j-w[i]>=0)//可以放入当前物品,选择放入则之前的空间减小。也可以选择不放入
dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-w[i]]+v[j]);
else //无法放入,只能计算0...i-1 在对应空间产生的价值
dp[i][j]=dp[i-1][j];
}
return dp[n-1][cap];
}
}
数量限制背包问题
有n件物品和容量为m的背包 给出i件物品的重量以及价值 求解让装入背包的物品重量不超过背包容量 且价值最大
解析:
这个问题和我们刚解决的01背包问题很像,不同的是该问题中的物品每一件有若干件,而01背包中的每一件物品只有一件.
动态规划(DP):
1) 子问题定义:F[i][j]表示前i种物品中选取若干件物品放入剩余空间为j的背包中所能得到的最大价值。
2) 根据第i种物品放多少件进行决策,我们可以将该问题转化为01背包问题求解,对于特定的容量,每一件物品最多放V/C[i]件,然后按照01背包dp
//伪代码如下:n为物品类别数,m为背包承重量,value[n] 物品价值,need[n]物品需要空间,k表明对应该物品的数量
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
for(k=0;k*need[i]<=j;k++){
dp[i][j]=max(dp[i][j],dp[i-1][j-k*need[i]]+value[i]);
}
}
}
return dp[n][m]
//优化
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++){
if(j>need[i])
dp[i][j]=Math.max(dp[i-1][j],dp[i][j-need[i]]+value[i]); //注意这里与0-1 背包不一样
else
dp[i][j]=dp[i-1][j];
}
}
return dp[n][m];