欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 【代码随想录第37天| 完全背包,518. 零钱兑换 II ,377. 组合总和 Ⅳ,70. 爬楼梯 (进阶)】

【代码随想录第37天| 完全背包,518. 零钱兑换 II ,377. 组合总和 Ⅳ,70. 爬楼梯 (进阶)】

2024/10/24 20:12:58 来源:https://blog.csdn.net/weixin_45891809/article/details/140782564  浏览:    关键词:【代码随想录第37天| 完全背包,518. 零钱兑换 II ,377. 组合总和 Ⅳ,70. 爬楼梯 (进阶)】

完全背包

完全背包中,每件物品都有无数件;这主要影响了遍历背包容量时的遍历顺序,应该从小到大去遍历,这样才能包括有多件相同物品的情况。

思路

先遍历物品,再遍历背包

for(int i = 0; i < weight.size(); i++) { // 遍历物品for(int j = weight[i]; j <= bagWeight ; j++) { // 遍历背包容量dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}
}

先遍历背包,再遍历物品

for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量for(int i = 0; i < weight.size(); i++) { // 遍历物品if (j - weight[i] >= 0) dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}
}

代码随想录

# include <bits/stdc++.h>using namespace std;int main() {int N, V;cin >> N >> V; vector<int>weight;vector<int>value;for (int i = 0; i < N; i++) {int w, v;cin >> w >> v;weight.push_back(w);value.push_back(v);}vector<int> dp(V + 1, 0);for (int i = 0; i < weight.size(); i++) {for (int j = weight[i]; j <= V; j++) {dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}}cout << dp[V] << endl;return 0;
}

518. 零钱兑换 II

思路

  • 组合个数问题,使用递推公式 : dp[j] += dp[j - nums(i)]

代码随想录

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];   }
};

377. 组合总和 Ⅳ

思路

  • 组合不强调顺序,外层for循环遍历物品,内层for循环遍历背包
  • 排列强调顺序, 外层for循环遍历背包, 内层for循环遍历物品
  • 本题虽然叫组合总和,但是看示例1,还是对顺序有要求的。

代码随想录

class Solution {
public:int combinationSum4(vector<int>& nums, int target) {sort(nums.begin(), nums.end());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 (i - nums[j] >= 0 && dp[i] < INT32_MAX - dp[i - nums[j]] ) {dp[i] += dp[i - nums[j]];}}}return dp[target];}
};

70. 爬楼梯 (进阶)

思路

  • 把能跨的步数堪看成物品,总共有m件物品,放满容量为n的背包(台阶)。
  • 记录次数的递推公式均为dp[i] += dp[i - nums[j]]形式
  • 本题是排列,因此先遍历背包。

代码随想录

# include <bits/stdc++.h>using namespace std;int main() {int n, m;cin >> n >> m;vector<int> dp(n + 1, 0);dp[0] = 1;for (int i = 1; i <= n; i ++) {for (int j = 1; j <= m; j++) {if (i - j >= 0) dp[i] += dp[i - j];}}cout << dp[n]<< endl;return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com