代码随想录算法训练营第三十四天| 完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ

完全背包  

区别:

每种物品都是可以无线多个

代码:

 1 // 多背包问题
 2 // 有N个物品,他们的体积和重量如下,但是这些物品有无限个
 3 // 需要发挥背包的最大容量,来让价值最大
 4 // 
 5 // dp[n]: 当容量为N的时候,背包的价值最大是多少
 6 // dp[n]: 
 7 //    dp[n]
 8 //    dp[n-weight[i]]+values[i]
 9 // 
10 // dp[0] = 0
11 //
12 int test_CompletePack(vector<int>& weight, vector<int>& value, int& bagWeight) 
13 {
14     vector<int> dp(bagWeight + 1, 0);
15 
16     for (int i = 0; i < weight.size(); i++)
17     {
18         for (int j = weight[i]; j <= bagWeight; j++)
19         {
20             dp[j] = max(dp[j], value[i] + dp[j - weight[i]]);
21         }
22     }
23 
24     return dp[bagWeight];
25 }

 518. 零钱兑换 II

难点——多少种方法再深入思考:

1 // dp[n] : 当容量为N 时,它的组合数
2 // 
3 // 重要的问题:不是 dp[j] = 1+dp[j-nums[i]] 得到满足J时有多少种方法
4 // 它的含义是 满足J时,它的最大子集数是多少
5 // 
6 // 多少种方法 dp[5]: dp[1]+4, dp[2]+3 其实共有 dp[1]+dp[2]这几种方法
7 // 
8 // 初始化的时候需要为dp[0]=1

所以只要遇到 需要多少种方法的时候都要用

dp[j]+=dp[j-nums[i]];

代码:

 1 // 要求:有这几个面值,需要组合这些面值和为目标值
 2 // 
 3 // 思路:物品的weight value都是coins
 4 // 
 5 // dp[n] : 当容量为N 时,它的组合数
 6 // 
 7 // 重要的问题:不是 dp[j] = 1+dp[j-nums[i]] 得到满足J时有多少种方法
 8 // 它的含义是 满足J时,它的最大子集数是多少
 9 // 
10 // 多少种方法 dp[5]: dp[1]+4, dp[2]+3 其实共有 dp[1]+dp[2]这几种方法
11 // 
12 // 初始化的时候需要为dp[0]=1
13 // 
14 //
15 int change(int amount, vector<int>& coins) {
16 
17     vector<int> dp(amount + 1, 0);
18 
19 
20     dp[0] = 1;
21     for (int i = 0; i < coins.size(); i++)
22     {
23         for (int j = coins[i]; j <= amount; j++)
24         {
25             dp[j] += dp[j - coins[i]];
26         }
27     }
28 
29 
30     return dp[amount];
31 }

 377. 组合总和 Ⅳ  

区别:

这个是排列问题

需要先遍历背包,再遍历物品

因为会有超出范围的警告,所以需要dp[j]<INT_MAX- dp[j - nums[i]]

代码:

 1 // 要求:不同整数,返回总和为target的组合个数
 2 // 难点:里面的数字的个数是无限多
 3 // 
 4 // 完全背包问题:
 5 // 
 6 // dp[n]:当总和为N时,组合个数
 7 // 
 8 // dp[j] += dp[j-nums[i]];
 9 //
10 int combinationSum4(vector<int>& nums, int target) {
11     vector<int> dp(target + 1, 0);
12 
13     dp[0] = 1;
14 
15     for (int j = 0; j <= target; j++)
16     {
17         for (int i = 0; i < nums.size(); i++)
18         {
19             if (j >= nums[i] && dp[j]<INT_MAX- dp[j - nums[i]])
20                 dp[j] += dp[j - nums[i]];
21         }
22     }
23 
24 
25     return dp[target];
26 }

 

posted @ 2023-07-20 09:24  博二爷  阅读(3)  评论(0编辑  收藏  举报