本文主要是介绍代码随想录算法训练营第四十四天 | 卡码网52. 携带研究材料 ,LeetCode 518. 零钱兑换 II , 377. 组合总和 Ⅳ,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接:52. 携带研究材料(第七期模拟笔试) (kamacoder.com)
#include<bits/stdc++.h>
using namespace std;int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);int n,v;cin>>n>>v;vector<int> dp(v+1,0);vector<int> weight(n,0);vector<int> val(n,0);for(int i=0;i<n;i++){cin>>weight[i]>>val[i];}for(int i=0;i<n;i++){for(int j=0;j<dp.size();j++){if(j>=weight[i]) dp[j]=max(dp[j],dp[j-weight[i]]+val[i]);}}cout<<dp[v]<<endl;return 0;
}
代码随想录 (programmercarl.com)
和01背包差不多,滚动数组01背包是第一层从前到后,第二层循环从后到前。这个完全背包两个循环都是从前到后。
题目链接:518. 零钱兑换 II - 力扣(LeetCode)
class Solution {
public:int change(int amount, vector<int>& coins) {vector<int> dp(amount+1,0);dp[0]=1;for(int i=0;i<coins.size();i++){for(int j=coins[i];j<=amount;j++){dp[j]+=dp[j-coins[i]];}}return dp[amount];}
};
代码随想录 (programmercarl.com)
跟之前做的一道题有点相似,也是累加的,区别是01背包和完全背包。
题目链接:377. 组合总和 Ⅳ - 力扣(LeetCode)
class Solution {
public:int combinationSum4(vector<int>& nums, int target) {vector<int> dp(target+1,0);dp[0]=1;for(int i=0;i<=target;i++){for(int j=0;j<nums.size();j++){if(nums[j]<=i && dp[i] < INT_MAX - dp[i - nums[j]])dp[i]+=dp[i-nums[j]];}}return dp[target];}
};
在动态规划:518.零钱兑换II (opens new window)中就已经讲过了。
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
如果把遍历nums(物品)放在外循环,遍历target的作为内循环的话,举一个例子:计算dp[4]的时候,结果集只有 {1,3} 这样的集合,不会有{3,1}这样的集合,因为nums遍历放在外层,3只能出现在1后面!
所以本题遍历顺序最终遍历顺序:target(背包)放在外循环,将nums(物品)放在内循环,内循环从前到后遍历。
这题对哪个循环在外层还是很有讲究的。
这篇关于代码随想录算法训练营第四十四天 | 卡码网52. 携带研究材料 ,LeetCode 518. 零钱兑换 II , 377. 组合总和 Ⅳ的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!