public class bag01 {
public static void main(String[] args)
{
int[] weight = {1,3,4};
int[] value = {15,20,30};
int bagsize = 4;
testbag(weight,value,bagsize);
}
public static void testbag(int[] weight,int[] value,int bagsize)
{
//第一步,创建dp数组,并明确dp数组的含义是什么
int[][]dp = new int[weight.length][bagsize+1];
//这里的dp数组的含义是我们从0-x下标里面选取,在容积为j的背包里面所能放下的最大的商品的价值
//第二步,推出递推公式
//当我们来到dp[i][j]的时候,有两大种可能,三小种可能
//第一大种可能 weight[i]>j重量超过了我们的背包的容量!我们就算把背包里面的东西全拿出来,也放不下这个新的物品
//所以,在这种情况,我们的dp[i][j]直接等于dp[i-1][j]因为我们知道这个i的东西本来就放不下了
//第二大种可能 weight[i]<=j这就说明,我们的背包可能可以放下weight[i]
//首先,我们考虑放下weight[i],因为要放下i,所以咱就得给这个东西腾位置,其他的东西占的位置得是
//j-weight[i]这样才给我们的i提供了能放下它的位置,那么其他的东西从哪个到那个呢?
//没错!就是从0到i-1,我们选择dp[i-1][j-weight[i]]+value[i]为我们选择放weight[1]的值
//有的同学看到放进去新的东西了非常的高兴,认为这样就结束了,其实不然,有的时候我们放东西不如不放新东西!
//好比如说我们原来的包里装的满满当当的钻石,你一遇到个石头就激动的嗷嗷叫,把钻石全甩出去了,装了一块大石头回家
//所以啊,我们有的时候装了新东西还不如不装!,如果是不装的情况我们的dp[i][j] = dp[i-1][j]
//~~~~这就是我们递推公式的推导
//第三步,初始化我们的dp数组
//首先再明确一下我们的dp数组的含义-->dp[i][j]代表着从下标0-i中选取,放到容积为j的背包的所有物品的最大值
//所以,当我们的容积为0的时候,dp的值为0
for(int i = 0;i<weight.length;i++)
{
dp[i][0] = 0;
//背包的容积为0,里面不可能有东西
}
for(int i = weight[0];i<=bagsize;i++)
{
dp[0][i] = value[0];
}
//接着由于我们的dp[i]都是由dp[i-1]确定的,所以,我们还得要初始化第0行
//好的,我们现在完成了初始化,可以开始遍历我们的数组了!
//我们按照先遍历物品,再遍历背包的重量
for(int i = 1;i<weight.length;i++)
{
for(int j = 0;j<=bagsize;j++)
{
if(j<weight[i]) {
dp[i][j] = dp[i-1][j];
}else
{
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]);
}
}
}
for(int i = 0;i<weight.length;i++)
{
for(int j = 0;j<=bagsize;j++)
{
System.out.print(dp[i][j]);
}
System.out.println();
}
}
}
01背包的二维数组的逻辑
最新推荐文章于 2023-07-12 20:09:05 发布