代码随想录算法训练营29期Day42|卡码网46,LeetCode 416

  文档讲解:背包问题二维  背包问题一维  分割等和子集

46.整数拆分

题目链接:https://kamacoder.com/problempage.php?pid=1046

思路:

       在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。

       dp[j]可以通过dp[j - weight[i]]推导出来,dp[j - weight[i]]表示容量为j - weight[i]的背包所背的最大价值。

       dp[j - weight[i]] + value[i] 表示 容量为 j - 物品i重量 的背包 加上 物品i的价值。(也就是容量为j的背包,放入物品i了之后的价值即:dp[j])

       此时dp[j]有两个选择,一个是取自己dp[j] 相当于 二维dp数组中的dp[i-1][j],即不放物品i,一个是取dp[j - weight[i]] + value[i],即放物品i,指定是取最大的,毕竟是求最大价值。

核心代码:

#include 
#include 
using namespace std;
int main() {
    // 读取 M 和 N
    int M, N;
    cin >> M >> N;
    vector costs(M);
    vector values(M);
    for (int i = 0; i < M; i++) {
        cin >> costs[i];
    }
    for (int j = 0; j < M; j++) {
        cin >> values[j];
    }
    vector dp(N + 1, 0);
    for (int i = 0; i < M; ++i) {
        for (int j = N; j >= costs[i]; --j) {
            dp[j] = max(dp[j], dp[j - costs[i]] + values[i]);
        }
    }

    cout << dp[N] << endl;
    return 0;
}

416.分割等和子集

题目链接:https://leetcode.cn/problems/partition-equal-subset-sum/description/

思路:

       分析可知以下几点:

       1.背包的体积为sum / 2

       2.背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值

       3.背包如果正好装满,说明找到了总和为 sum / 2 的子集。

       4.背包中每一个元素是不可重复放入。

       可知题目为01背包,套模板即可。

核心代码:

class Solution {
public:
    bool canPartition(vector& nums) {
        int sum = 0;
        vector dp(10001, 0);
        for (int i = 0; i < nums.size(); i++) {
            sum += nums[i];
        }
        if (sum % 2 == 1) return false;
        int target = sum / 2;
        for(int i = 0; i < nums.size(); i++) {
            for(int j = target; j >= nums[i]; j--) {
                dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
            }
        }
        if (dp[target] == target) return true;
        return false;
    }
};

今日总结

        今日学习时长2h,算是复习了背包问题。

        参加了华为主管面,感觉寄掉了,寄寄寄。

        接着冲击八股文。

你可能感兴趣的:(代码随想录算法训练营29期,算法,leetcode,职场和发展,c++,动态规划)