算法第37天| 完全背包\518. 零钱兑换 II\377. 组合总和 Ⅳ\57. 爬楼梯
完全背包
完全背包和01背包的区别
纯完全背包,遍历背包和物品的顺序是可以对调的,只要求得出最大价值,不要求凑成总和的元素的顺序;
01背包,遍历背包和物品的顺序是不可以对调的(一维不行,二维是可以的);
一维解法中 遍历顺序 主要就是用来保证物品 不被重复使用 的,而完全背包中物品本身就是可以重复使用的,所以就无所谓了。
完全背包
题目
思路与解法
#include <iostream>
#include <vector>
using namespace std;int main(){int n; // 物品种类int v; // 背包大小cin >> n >> v;vector<int> weight(n, 0); // 物品重量vector<int> value(n, 0); // 物品价值for(int i=0;i<n;i++){cin >> weight[i] >> value[i];}// for(int i=0;i<n;i++){// cout<< weight[i];// cout<< value[i]<<" ";// }// dp数组含义:// dp[i]: 背包容量为i时,放入小于等于当前序号的物品所能达到的最大价值vector<int> dp(v+1, 0);// 先遍历 物品for(int i=0;i<n;i++){// 后遍历 背包for(int j=weight[i];j<=v;j++){dp[j] = max(dp[j-weight[i]]+value[i], dp[j]);}}cout << dp[v] << endl;return 0;
}
518. 零钱兑换 II
题目
思路与解法
class Solution {
public:int change(int amount, vector<int>& coins) {// dp数组含义:// dp[i]: 总金额为i时,使用小于大于当前硬币序号的硬币能凑成总金额的方式总数vector<uint64_t> 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];}
};
377. 组合总和 Ⅳ
题目
思路与解法
class Solution {
public:int combinationSum4(vector<int>& nums, int target) {//dp数组含义:组合的个数vector<uint64_t> 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] += dp[i-nums[j]];}}return dp[target];}
};
57. 爬楼梯(第八期模拟笔试)
题目
思路与解法
#include<iostream>#include <vector>using namespace std;int main(){int n, m; //n:总数,m:步长范围cin >> n >> m;// dp数组含义:// 方式总数vector<int> dp(n+1, 0);dp[0] = 1;// 先背包再物品 因为求的是排列// 反过来就是求组合for(int i = 0;i<=n;i++){for(int j = 1;j<=m;j++){if(j <= i) dp[i] += dp[i-j]; }}cout << dp[n] << endl;return 0;}