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]);
}
}
01背包问题(滚动数组实现的逻辑)
最新推荐文章于 2024-05-11 18:12:01 发布