方法一 : 二维数组解法
1.dp数组
dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少
2.dp数组初始化
dp[i][0] 无论放什么物品 背包空间为0 所以最大价值和为0; 但是开始初始化时候,已经覆盖了
对于第一行来说 当背包的空间满足第一个物品的cost后,最大值就可以更新了
3.递推公式
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
其中dp[i - 1][j] 这个是第i个没放进来
dp[i - 1][j - weight[i]] + value[i] 这个是第i个放进来
取其中的最大值
4.遍历顺序
先物品后背包 或 先背包后物品都可以
因为是由上一次更新 所以都不影响
方法二 : 一维dp数组
1.dp数组
dp[j]表示 容量为j的背包,所背的物品价值可以最大为dp[j]
2.dp数组初始化
dp[0]就是0 因为容量为0的时候 价值就是0
3.递推公式
dp[j+1] 是由dp[j]迭代而来,dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
dp[j]就是什么都还没加,dp[j - weight[i]] + value[i] 加了下一个
4.遍历顺序
1.一定是背包倒叙 不然之前的物品会多次取
2.只能是先物品后背包 因为一维dp的写法,背包容量一定是要倒序遍历(原因上面已经讲了),如果遍历背包容量放在上一层,那么每个dp[j]就只会放入一个物品,即:背包里只放入了一个物品
根本逻辑跟上面是一样的 只是加了一点别的东西 当最大值为和的一半时就可以了