- 完全背包
- 和01背包的区别是遍历顺序的不同
- 注意看是求组合 还是排序
- 518. 零钱兑换 II
- 完全背包问题 => 求组合(不强调顺序) => 外层物品 内层背包
- 377. 组合总和 Ⅳ
- 求排列 => 在意顺序 => 完全背包 => 先背包 再物品
package algor.trainingcamp.backpack;
/**
* @author lizhe
* @version 1.0
* @description: 完全背包
* @date 2023/5/18 07:53
*
* 有N件物品和一个最多能背重量为W的背包。
* 第i件物品的重量是weight[i],得到的价值是value[i] 。
* 每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。
*
* 完全背包和01背包问题唯一不同的地方就是,每种物品有无限件。
*
* 和01背包的区别是 使用一维时,遍历可以无视顺序,且遍历背包时,可以正序
*/
public class Problem2 {
private static void testCompletePack(){
int[] weight = {1, 3, 4};
int[] value = {15, 20, 30};
int bagWeight = 4;
int[] dp = new int[bagWeight + 1];
for (int i = 0; i < weight.length; i++){ // 遍历物品
for (int j = weight[i]; j <= bagWeight; j++){ // 遍历背包容量
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
}
}
for (int maxValue : dp){
System.out.println(maxValue + " ");
}
}
//先遍历背包,再遍历物品
private static void testCompletePackAnotherWay(){
int[] weight = {1, 3, 4};
int[] value = {15, 20, 30};
int bagWeight = 4;
int[] dp = new int[bagWeight + 1];
for (int i = 1; i <= bagWeight; i++){ // 遍历背包容量
for (int j = 0; j < weight.length; j++){ // 遍历物品
if (i - weight[j] >= 0){
dp[i] = Math.max(dp[i], dp[i - weight[j]] + value[j]);
}
}
}
for (int maxValue : dp){
System.out.println(maxValue + " ");
}
}
}
package algor.trainingcamp.backpack;
/**
* @author lizhe
* @version 1.0
* @description: 给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。
* @date 2023/5/18 07:57
*
* dp[j]:凑成总金额j的货币组合数为dp[j]
* dp[j] += dp[j - coins[i]];
*
* 完全背包问题 => 求组合(不强调顺序) => 外层物品 内层背包
*/
public class LeetCode518 {
public int change(int amount, int[] coins) {
int[] dp = new int[amount + 1];
dp[0] = 1;
for(int i = 0;i < coins.length;i++){
for(int j = coins[i];j <= amount;j++){
dp[j] += dp[j - coins[i]];
}
}
return dp[amount];
}
}
package algor.trainingcamp.backpack;
/**
* @author lizhe
* @version 1.0
* @description: TODO
* @date 2023/5/18 08:01
* <p>
* 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。
* <p>
* 题目数据保证答案符合 32 位整数范围。
* <p>
* 求排列 => 在意顺序 => 完全背包 => 先背包 再物品
* 来源:力扣(LeetCode)
* 链接:https://leetcode.cn/problems/combination-sum-iv
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
*/
public class LeetCode377 {
public int combinationSum4(int[] nums, int target) {
int[] dp = new int[target + 1];
dp[0] = 1;
for (int j = 0; j <= target; j++) {
for (int i = 0; i < nums.length; i++) {
if(j > nums[i]){
dp[j] += dp[j - nums[i]];
}
}
}
return dp[target];
}
}