首页 > 编程语言 >代码随想录算法训练营第四十三天 | 52.携带研究材料 518.零钱总和II 377.组合总和IV 70.爬楼梯

代码随想录算法训练营第四十三天 | 52.携带研究材料 518.零钱总和II 377.组合总和IV 70.爬楼梯

时间:2024-07-01 17:54:33浏览次数:1  
标签:vector 遍历 四十三天 int 随想录 背包 物品 dp 总和

完全背包

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

标签:vector,遍历,四十三天,int,随想录,背包,物品,dp,总和
From: https://www.cnblogs.com/cscpp/p/18278552

相关文章