1. 背包问题总结
![在这里插入图片描述](https://img-blog.csdnimg.cn/4dccad29e4fb477586a9a4a6c97d1396.png)
2.动态规划解题步骤
- 定义dp数组,了解dp数组及其下标含义
- 递推关系
- dp数组初始化
- 打印dp数组
- 举例推导dp数组
2.1 确定递推公式
- 问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
- 问装满背包有几种方法:dp[j] += dp[j - nums[i]]
- 问背包装满最大价值:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
- 问装满背包所有物品的最小个数:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
2.2遍历顺序
2.2.1 01背包
- 二维dp数组01背包先遍历物品还是先遍历背包都是可以的,且第二层for循环是从小到大遍历。
- 一维dp数组01背包只能先遍历物品再遍历背包容量,且第二层for循环是从大到小遍历。
for(int i = 0;i < nums.length;i++){
for(int j = target;j >= nums[i];j--){
dp[j] = Math.max(dp[j],dp[j-nums[i]] + nums[i]);
}
}
2.2.2 完全背包
- 如果求组合数就是外层for循环遍历物品,内层for遍历背包。
for (int i = 0; i < coins.size(); i++) {
for (int j = coins[i]; j <= amount; j++) {
dp[j] += dp[j - coins[i]];
}
}
- 如果求排列数就是外层for遍历背包,内层for循环遍历物品。
for (int j = 0; j <= amount; j++) {
for (int i = 0; i < coins.size(); i++) {
if (j - coins[i] >= 0) dp[j] += dp[j - coins[i]];
}
}
多重背包暂时先跳过