01背包问题(滚动数组实现的逻辑)

package tttest;

public class mybetterbag {
	public static void main(String[] args)
	{
		int[] weight = {1,3,4};
		int bagsize = 4;
		int[] value = {15,20,30};
		happy(weight,value,bagsize);
	}
	public static void happy(int[] weight,int[] value,int bagsize)
	{
		//我们使用滚动数组来帮我们解决这道题
		//第一步,先定义dp,并且明确dp的含义
		int[] dp = new int[bagsize+1];
		//这里我们的dp意思是容量为i的背包,最多能装价值为dp[i]的东西
		//我们为什么使用一维数组而不使用二维数组呢?
		//我们使用一维数组的原理是什么呢?
		//我们先看二维数组时,我们的代码
		//dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i])、
		//如果我们把i-1行直接复制到i行
		//则变成 dp[i][j] = Math.max(dp[i][j],dp[i-weight[i]][j]+value[i])
		//因为我们提前赋值了,如果,我们的值不变化,那么我们dp[i][j]的值就不变
		//本来是等于dp[i-1][j]的值,但是由于我们已经赋过值了,我们dp[i][j]的值本来就是dp[i-1][j]的值了
		//所以,我们就可以不变
		//与其我们把上一行的数值赋给下一行,不如我们直接在这一行进行修改
		//我们dp[j] = Math.max(dp[j],dp[j-weight[i]]+value[i])
		//当我们来到dp[j]的时候,我们dp[j]里面的值就是上一轮dp中的值,如果我们不加新物品,那么我们dp[j]的值就不用修改
		//所以,dp[j]中的值就不改变
		//但是如果我们的值需要修改呢?那么,我们的dp[j] = dp[j-weight[i]]+value[i]
		//大家回想一下,如果我们的dp[j]需要改变,在二维数组里面我们是怎么做的?
		//dp[i][j] = dp[i-1][j-weight[i]]+value[i]
		//我们为了方便,拿数组的本身来记录上一层的对应值,所以,我们的dp[j] = dp[j-weight[i]]+value[i]
		//但是这里还需要注意很重要的一点!!
		//我们拿数组本身记录上一层的数据,那么我们的数组j修改过后,就不再是上一层的数据了,他就变成这一层的数据了
		//如果我们选择从前往后遍历的话,当j-weight[i]回到前面的数据时,我们得到的不是我们想要到上一层数据,而是从上一层数据经过变化来到的本层的数据
		//这就不好了!,我们本来是dp[i-1][j-weight[i]]+value[i]
		//如果我们从前往后遍历的话,就成为了dp[i][j-weight[i]] + value[i]
		//这显然不对,为了避免使用被改变的数据,我们从后往前遍历
		//这样被修改的数据也是从后往前
		//就不用担心层数的问题了!
		for(int i = 0;i<weight.length;i++)
		{
			for(int j = bagsize;j>=weight[i];j--)
			{
				dp[j] = Math.max(dp[j],dp[j-weight[i]]+value[i]);
			}
		}
		System.out.println(dp[bagsize]);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值