代码随想录算法训练营第41天 [01背包的理论基础,二维数组解法,一维数组解法,416. 分割等和子集]

代码随想录算法训练营第41天 [01背包的理论基础,二维数组解法,一维数组解法,416. 分割等和子集]


一、01背包的二维数组解法

链接: 代码随想录.
思路:dp数组, dp[i][j]代表行李箱空间为j的情况下,从下标为[0, i]的物品里面任意取,能达到的最大价值,递推公式为 dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i])
做题状态:看解析后做出来了

//二维dp数组实现
#include <bits/stdc++.h>
using namespace std;

int n, bagweight;// bagweight代表行李箱空间


void solve() {
    vector<int> weight(n, 0); // 存储每件物品所占空间
    vector<int> value(n, 0);  // 存储每件物品价值
    for(int i = 0; i < n; ++i) {
        cin >> weight[i];
    }
    for(int j = 0; j < n; ++j) {
        cin >> value[j];
    }
    // dp数组
    // dp[i][j]代表行李箱空间为j的情况下,从下标为[0, i]的物品里面任意取,能达到的最大价值
    vector<vector<int>> dp(n,vector<int>(bagweight+1,0));
    for(int j = 0 ;j<=bagweight;j++){
        if(j >= weight[0]){
            dp[0][j] = value[0];
        }
    }


    for(int i = 1;i<n;i++){
        for(int j = 0;j<=bagweight;j++){
            if(weight[i]>j){
                dp[i][j] = dp[i-1][j];
            }else{
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);
            }
        }
    }

    cout << dp[n-1][bagweight] <<endl;
}


int main() {
    while(cin >> n >> bagweight) {
        solve();
    }
    return 0;
}

二、01背包的一维数组解法

链接: 代码随想录.
思路:
一维数组实现 dp数组的含义 dp[j] 在背包大小为j时的最大价值
二维数组的递推公式为 dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]+value[i])
一维数组的递推公式为 dp[j] = max(dp[j],dp[j-weight[i]+value[i])
一维数组的解法里,必须先遍历物品,再遍历背包
并且遍历背包的时候必须时倒序
j代表空间,空间必须比我选择的物品i的容量要大,所以时j>=weight[i]
做题状态:看解析后做出来了

//二维dp数组实现
#include <bits/stdc++.h>
using namespace std;

int n, bagweight;// bagweight代表行李箱空间


void solve() {
    vector<int> weight(n, 0); // 存储每件物品所占空间
    vector<int> value(n, 0);  // 存储每件物品价值
    for(int i = 0; i < n; ++i) {
        cin >> weight[i];
    }
    for(int j = 0; j < n; ++j) {
        cin >> value[j];
    }
    //一维数组实现 dp数组的含义 dp[j] 在背包大小为j时的最大价值
    //二维数组的递推公式为 dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]+value[i])
    //一维数组的递推公式为 dp[j] = max(dp[j],dp[j-weight[i]+value[i])
    vector<int> dp(bagweight+1,0);
    //一维数组的解法里,必须先遍历物品,再遍历背包
    //并且遍历背包的时候必须时倒序
    
    //j代表空间,空间必须比我选择的物品i的容量要大,所以时j>=weight[i]
    for(int i = 0;i<n;i++){
        for(int j = bagweight;j>=weight[i];j--){
            dp[j] = max(dp[j],dp[j-weight[i]]+value[i]);
        }
    }
    cout << dp[bagweight] <<endl;
}


int main() {
    while(cin >> n >> bagweight) {
        solve();
    }
    return 0;
}

三、416. 分割等和子集

链接: 代码随想录.
思路:把问题转化为01背包,
相当于从nums里取数,重量 = 价值 = 数值
有一个大小为target的背包,能不能将背包装满
做题状态:看解析后做出来了

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        vector<int> dp(10001, 0);
        int sum = 0;
        for (int n : nums) {
            sum += n;
        }
        if (sum % 2 == 1) {
            return false;
        }
        int target = sum / 2;
        // 相当于从nums里取数,重量 = 价值 = 数值
        // 有一个大小为target的背包,能不能将背包装满
        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]);
            }
        }

        return dp[target] == target;
    }
};

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-06-18 10:28:04       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-18 10:28:04       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-18 10:28:04       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-18 10:28:04       18 阅读

热门阅读

  1. 考研计算机网络(第一章 概述)

    2024-06-18 10:28:04       7 阅读
  2. Babelfish for PostgreSQL

    2024-06-18 10:28:04       9 阅读
  3. CCAA认证人员考试各科涉及法律法规汇总

    2024-06-18 10:28:04       8 阅读
  4. PHP框架有哪些,以及具体对比优缺点

    2024-06-18 10:28:04       6 阅读
  5. 数据仓库之Kappa架构

    2024-06-18 10:28:04       10 阅读
  6. iommu深度剖析虚拟化技术的隐形守护者

    2024-06-18 10:28:04       8 阅读