01背包的二维数组的逻辑

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();
		}
		
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值