代码随想录算法训练营第四十三天 | 52.携带研究材料 518.零钱总和II 377.组合总和IV 70.爬楼梯
完全背包
有N件物品和一个最多能被重量为W的背包,第i间物品的重量为weights[i],价值为value[i],每件物品都有无限个,求解将哪些物品装入背包里,物品价值总和最大
遍历顺序:纯完全背包问题(即求装满背包后的最大价值)先遍历背包先遍历物品都是可以的
和零一背包求解的最大不同就是遍历顺序,完全背包先遍历物品和先遍历背包都可以,遍历背包时应从小到大遍历
52.携带研究材料
- dp[j]: 表示装满容量为j的背包,最大的价值为dp[j]
- 递推公式:dp[j] = max(dp[j-weights[i]] + value[i], dp[j])
- 初始化:dp[0] = 0;
- 遍历顺寻:先遍历物品和先遍历背包都可以,遍历背包时正序遍历(从小到大)
- 打印dp数组
#include <iostream>
#include <vector>
using namespace std;
int main() {
int N, V;
while(cin >> N >> V) {
// N 表示研究材料种类
// V 表示行李空间
vector<int> weights(N);
vector<int> value(N);
for(int i = 0; i < N; ++i) {
cin >> weights[i] >> value[i];
}
// dp[j] 表示容量为j的背包所装物品的最大价值
vector<int> dp(V + 1, 0);
// 递推公式: dp[j] = max(dp[j - weight[i]] + value[i], dp[j])
// 初始化: dp[j] = 0;
// 遍历顺序,先遍历物品后遍历背包都可以,下面先遍历物品
// 因为每个物品可以装多个,所以背包正序遍历
for(int i = 0; i < N; ++i) {
for(int j = 1; j <= V; ++j) {
if(j >= weights[i]) dp[j] = max(dp[j-weights[i]] + value[i], dp[j]);
}
}
cout << dp[V];
}
return 0;
}
518.零钱兑换II
- dp[j]: 凑成面额为j,有dp[j]种方法
- 递推公式:dp[j] += dp[j - coins[i]]
- 初始化: dp[0] = 1
- 遍历顺序:先遍历硬币后便利面额,面额从小到大遍历
- 打印dp数组
关于遍历顺序:
class Solution {
public:
int change(int amount, vector<int>& coins) {
// dp[j]: 表示凑成j的面额有多少种方法
vector<int> dp(amount + 1, 0);
// 递推公式: max(dp[j] = dp[j - coins[i]] + 1, dp[j])
// 初始化dp[0] = 1
dp[0] = 1;
// 遍历
for(int i = 0; i < coins.size(); ++i) {
for(int j = 1; j <= amount; ++j) {
if(j >= coins[i]) dp[j] += dp[j - coins[i]];
}
}
for(int val : dp) cout << val << " ";
return dp[amount];
}
};
377.组合总和IV
class Solution {
public:
int combinationSum4(vector<int>& nums, int target) {
vector<int> dp(target + 1, 0);
dp[0] = 1;
for(int j = 0; j <= target; ++j) {
for(int i = 0; i < nums.size(); ++i) {
if(j >= nums[i] && dp[j] < INT_MAX - dp[j - nums[i]]) dp[j] += dp[j - nums[i]];
}
}
return dp[target];
}
};
57.爬楼梯
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n, m;
while(cin >> n >> m) {
// dp[j]: 表示到达第j个楼梯有多少种方法
vector<int> dp(n + 1, 0);
// 递推公式: dp[j] += dp[j-i]
dp[0] = 1;
for(int j = 1; j <= n; ++j) {
for(int i = 0; i <= m; ++i) {
if(j >= i) dp[j] += dp[j-i];
}
}
// for(int val : dp) cout << val << " ";
cout << dp[n];
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构