当前位置:网站首页>力扣题解 动态规划(3)
力扣题解 动态规划(3)
2022-07-27 05:20:00 【RL-UAV】
0.1完全背包
/ 先遍历物品,在遍历背包
void test_CompletePack() {
vector<int> weight = {
1, 3, 4};
vector<int> value = {
15, 20, 30};
int bagWeight = 4;
vector<int> dp(bagWeight + 1, 0);
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]);
}
}
cout << dp[bagWeight] << endl;
}
int main() {
test_CompletePack();
}
518. 零钱兑换 II
是一道典型的背包问题,一看到钱币数量不限,就知道这是一个完全背包
在求装满背包有几种方案的时候,认清遍历顺序是非常关键的。
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
dp[j]:凑成总金额j的货币组合数为dp[j]
所以递推公式:dp[j] += dp[j - coins[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. 组合总和 Ⅳ
C++测试用例有两个数相加超过int的数据,所以需要在if里加上dp[i] < INT_MAX - dp[i - num]。
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 (i - nums[j] >= 0 && dp[i] < INT_MAX - dp[i - nums[j]]) {
dp[i] += dp[i - nums[j]];
}
}
}
return dp[target];
}
};
70. 爬楼梯
class Solution {
public:
int climbStairs(int n) {
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];
}
}
return dp[n];
}
};
代码中m表示最多可以爬m个台阶,代码中把m改成2就是本题70.爬楼梯可以AC的代码了。
322. 零钱兑换
而本题是要求最少硬币数量,硬币是组合数还是排列数都无所谓!所以两个for循环先后顺序怎样都可以!
// 版本一
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;
for (int i = 0; i < coins.size(); i++) {
// 遍历物品
for (int j = coins[i]; j <= amount; j++) {
// 遍历背包
if (dp[j - coins[i]] != INT_MAX) {
// 如果dp[j - coins[i]]是初始值则跳过
dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
}
}
}
if (dp[amount] == INT_MAX) return -1;
return dp[amount];
}
};
对于遍历方式遍历背包放在外循环,遍历物品放在内循环也是可以的,我就直接给出代码了
// 版本一
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;
for (int i = 0; i < coins.size(); i++) {
// 遍历物品
for (int j = coins[i]; j <= amount; j++) {
// 遍历背包
if (dp[j - coins[i]] != INT_MAX) {
// 如果dp[j - coins[i]]是初始值则跳过
dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
}
}
}
if (dp[amount] == INT_MAX) return -1;
return dp[amount];
}
};
边栏推荐
猜你喜欢

【头歌】重生之机器学习-线性回归

方差与协方差

3. Classification problems - initial experience of handwritten digit recognition

Auto Encoder(AE),Denoising Auto Encoder(DAE), Variational Auto Encoder(VAE) 区别

pytorch的多GPU训练的两种方式

Live Home 3D Pro interior home design tool

16. Over fitting and under fitting

LaTeX中多个公式公用一个序号时

Digital image processing Chapter 8 - image compression

图像超分辨率评价指标
随机推荐
百问网驱动大全学习(二)I2C驱动
Lightroom Classic 2022 v11.4中文版「最新资源」
Kaggle调用自定义模块方法
Multi task foundation of IOT operating system
【头歌】重生之CNN图片分类基础
[first song] rebirth of me in py introductory training (6): definition and application of functions
【12】理解电路:从电报机到门电路,我们如何做到“千里传信”?
【头歌】重生之数据科学导论——回归进阶
能替代ps的修图软件?
Live Home 3D Pro室内家居设计工具
【Arduino】重生之Arduino 学僧(1)
socket编程一:使用fork()实现最基础的并发模式
Greedy high performance neural network and AI chip application research and training
方差与协方差
对于windows下的Redis,只能读不能写的问题
[song] rebirth of me in py introductory training (8): module
Xmind 思维导图 2022 v12.0.3中文版更新了哪些内容?
【11】二进制编码:“手持两把锟斤拷,口中疾呼烫烫烫”?
pytorch中交叉熵损失函数的细节
socket编程二:使用select