代码随想录算法训练营第四十一天 | 01背包问题-二维数组滚动数组,416. 分割等和子集

news2024/11/16 11:46:27

一、参考资料

01背包问题 二维

https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html

视频讲解:https://www.bilibili.com/video/BV1cg411g7Y6

01背包问题 一维

https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-2.html

视频讲解:https://www.bilibili.com/video/BV1BU4y177kY

分割等和子集

本题是 01背包的应用类题目

https://programmercarl.com/0416.%E5%88%86%E5%89%B2%E7%AD%89%E5%92%8C%E5%AD%90%E9%9B%86.html

视频讲解:https://www.bilibili.com/video/BV1rt4y1N7jE

二、动态规划:01背包理论基础

背包问题:

01背包-二维数组 完整C++测试代码!
void test_2_wei_bag_problem1() {
    vector<int> weight = {1, 3, 4};
    vector<int> value = {15, 20, 30};
    int bagweight = 4;

    // 二维数组
    vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));

    // 初始化
    for (int j = weight[0]; j <= bagweight; j++) {
        dp[0][j] = value[0];
    }

    // weight数组的大小 就是物品个数
    for(int i = 1; i < weight.size(); i++) { // 遍历物品
        for(int j = 0; j <= bagweight; j++) { // 遍历背包容量
            if (j < weight[i]) 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[weight.size() - 1][bagweight] << endl;
}

int main() {
    test_2_wei_bag_problem1();
}

Tip1:关于二维遍历的顺序,先遍历背包重量还是先遍历物品都可以,影响的是一个是先生成行再生成下一行的某一个位置的值,另一个是先生成列再生成下一列某一个位置的值。

Tip2:初始化需要注意!背包重量为0所对应的行或者列应该全部初始化为0,编号为0的物品所对应的行或列的初始化需要根据当前背包所能承受的最大重量,与当前物品的重量相比,能放下就初始化为当前物品的value。

Tip3:双层for循环,内层是正序或倒序遍历均可以,这是因为二维数组的行和列的数值是相互独立不受影响的。以物品为行,重量为列举例,下一行装物品的dp[i][j]与dp[i-1][j]是完全独立的值,每一个新的行i都会根据历史信息更新,因此不受遍历顺序的影响。

01背包-一维数组 完整C++测试代码!(滚动数组)
void test_1_wei_bag_problem() {
    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 = bagWeight; j >= weight[i]; j--) { // 遍历背包容量
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
        }
    }
    cout << dp[bagWeight] << endl;
}

int main() {
    test_1_wei_bag_problem();
}

Tip:特别注意!!此时的内层循环一定要倒序遍历,这是为了防止重复拿物品。因为状态压缩后,当前行的数组是动态变化的,某一个位置dp[j]的产生或受到新旧数据的共同影响。因此,采用倒序遍历的方式,保证物品只拿一次,满足01背包的基本需求。

三、LeetCode416. 分割等和子集

https://leetcode.cn/problems/partition-equal-subset-sum/description/

给你一个 只包含正整数 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

示例 1:
输入:nums = [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。
示例 2:
输入:nums = [1,2,3,5] 输出:false 解释:数组不能分割成两个元素和相等的子集。
提示:
1 <= nums.length <= 200
1 <= nums[i] <= 100
class Solution {
public:
    bool canPartition(vector<int>& nums) {
        // 对数组来说,重量和价值是一样
        int sum = 0;

        // dp[i]中的i表示背包内总和
        // 题目中说:每个数组汇总的元素不会超过100,数组的大小不会超过200
        // 总和不会大于20000,背包最大只需要其中一半,所以10001大小就可以了
        vector<int> dp(10001, 0); 
        for (int i = 0; i < nums.size(); i++) {
            sum += nums[i];
        }
        // 也可以使用库函数一步求和
        // int sum = accumulate(nums.begin(), nums.end(), 0);
        if (sum % 2 == 1) return false;
        int target = sum / 2;

        // 开始01背包
        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]);
            }
        }
        // 集合中的元素正好可以凑成总和target
        if (dp[target] == target) return true;
        return false;
    }
};

补题哇~继续Day41 √

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/381365.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大功率分流电阻器产品阵容进一步扩大,助力大功率应用小型化

全球知名半导体制造商ROHM&#xff08;总部位于日本京都市&#xff09;面向车载、工业设备及白色家电等大功率应用&#xff0c;开发出大功率低阻值分流电阻器“GMR 系列”中额定功率最大的、10W 电阻器“GMR320”。近年来&#xff0c;在车载领域和工业设备领域中&#xff0c;应…

什么是敏捷测试

敏捷 反应快速灵敏。 在敏捷软件开发领域&#xff0c;更注重的以人为核心&#xff0c;迭代&#xff0c;循序渐进的开发方法。相比传统的开发方法&#xff0c;这种方法能更快速的开发&#xff0c;上线&#xff0c;反馈&#xff0c;调整、迭代。以敏捷的姿态去发展产品。 敏捷与…

基于java+swing+mysql员工工资管理系统

基于javaswingmysql员工工资管理系统一、系统介绍二、功能展示1.用户登陆2.员工主要功能3.管理员主要功能三、系统实现1.StudentFrame .java四、其它1.其他系统实现2.获取源码一、系统介绍 该项目功能相对完善&#xff0c;有管理员和普通用户两个角色&#xff0c;分别实现了一…

磷脂酰丝氨酸的作用;CAS:383907-32-2;磷脂酰丝氨酸(phosphatidylserine,PS)

磷脂酰丝氨酸&#xff08;phosphatidylserine&#xff0c;PS&#xff09;又称丝氨酸磷脂&#xff0c;二酰甘油酰磷酸丝氨酸&#xff0c;简称PS&#xff0c;是一类普遍存在的磷脂&#xff0c;通常位于细胞膜的内层&#xff0c;磷酯化合物中的磷酸甘油酯类&#xff0c;是细胞膜组…

数字化时代,企业如何通过技术改造传统客户服务模式

B端产品要从流量思维到客户思维上转变&#xff0c;良好的客户服务能够让B端企业走的越远走的越多&#xff0c;当然&#xff0c;对于所有产品或者企业来说&#xff0c;也唯有客户服务才是走的更远更久的保证&#xff0c;优秀的客户服务团队是企业的潜在优质财富。 搭建客服团队…

ATTO 647N-NHS ester,ATTO 647N SE,ATTO 647N NHS酯,适用于单分子检测应用

基础产品数据&#xff08;Basic Product Data&#xff09;&#xff1a;CAS号&#xff1a;N/A中文名&#xff1a;ATTO 647N-琥珀酰亚胺酯&#xff0c;ATTO 647N-活性酯&#xff0c;ATTO 647N NHS酯英文名&#xff1a;ATTO 647 N-NHS&#xff0c;ATTO647N-NHS&#xff0c;ATTO 64…

为什么转行IT行业都会选择学习Python?

现在学习Python的人越来越多了&#xff0c;很多人都疑惑为什么这么多人转行IT都会选择学Python?为什么学Python要参加Python培训班呢?接下来蛋糕为大家答疑解惑一下吧。 虽然Python已经非常普及&#xff0c;但是大部分的大学都还没有开设Python课程&#xff0c;如果想要学习…

XGBoost学习-应用案例

文章目录一、过拟合&#xff1a;剪枝参数与回归模型调参二、XGBoost模型的保存和调用使用Joblib保存和调用模型三、分类案例&#xff1a;XGB中的样本不均衡问题四、 XGBoost类中的其他参数和功能总结一、过拟合&#xff1a;剪枝参数与回归模型调参 class xgboost.XGBRegressor…

2023前端vue面试题(边面边更)

Vue中key的作用 vue 中 key 值的作用可以分为两种情况来考虑&#xff1a; 第一种情况是 v-if 中使用 key。由于 Vue 会尽可能高效地渲染元素&#xff0c;通常会复用已有元素而不是从头开始渲染。因此当使用 v-if 来实现元素切换的时候&#xff0c;如果切换前后含有相同类型的…

只用最适合的 | 主流 .NET 报表控件全面对比

随着 .NET 平台的出现&#xff0c;报表相关的开发控件随着而来&#xff0c;已经有若干成熟的产品可供开发人员使用&#xff0c;本文旨在通过从不同维度对比目前最流行的3款 .NET报表控件&#xff1a;FastReport、Stimulsoft、水晶报表&#xff0c;给所有报表开发人员在做产品选…

家用洗地机哪款最好用?全球洗地机十大品牌

近年来&#xff0c;智能家用电器洗地机已经融入到我们生活中了&#xff0c;成为最受欢迎的清洁工具了&#xff0c;家用洗地机吸拖洗一体&#xff0c;不用先扫后拖那么麻烦&#xff0c;只需轻轻一推&#xff0c;就能把扫地、拖地、擦地的活全干了&#xff0c;操作简单&#xff0…

【iOS】—— 初识RAC响应式编程

RAC&#xff08;ReactiveCocoa&#xff09; 文章目录RAC&#xff08;ReactiveCocoa&#xff09;响应式编程和函数式编程的区别函数式编程响应式编程响应式编程的优点RAC操作1.利用button点击实现点击事件和传值2.RACSignal用法RACSignal总结&#xff1a;3.对于label的TapGestur…

Java | IO 模式之 JavaNIO 应用

文章目录NIO1 Java NIO 基本介绍2 NIO 和 BIO 的比较3 NIO 三大核心原理示意图3.1 Buffer缓冲区3.2 Channel&#xff08;通道&#xff09;3.3 Selector选择器3.4 总结4 NIO核心一&#xff1a;缓冲区(Buffer)4.1 缓冲区&#xff08;Buffer&#xff09;4.2 Buffer 类及其子类4.3 …

泛型与Map接口

Java学习之道 泛型 泛型这种参数类型可以用在类、方法和接口中&#xff0c;分别被称为泛型类&#xff0c;泛型方法&#xff0c;泛型接口 参数化类型&#xff1a;将类型由原来的具体的类型参数化&#xff0c;在使用/调用时传入具体的类型JDK5引入特性提供了安全检测机制&#xf…

[oeasy]python0097_苹果诞生_史蒂夫_乔布斯_沃兹尼亚克_apple_I

苹果诞生 回忆上次内容 上次时代华纳公司 凭借手中的影视ip和资本吞并了雅达利公司 此时 雅达利公司 曾经开发过pong的 优秀员工 乔布斯 还在 印度禅修 寻找自我 看到游戏行业 蓬勃发展 乔布斯 也想有自己的 一番天地 可是 他的机会在哪里呢?&#x1f914; Jobs 跟着 Wozn…

顺序表——重置版

本期我们来实现数据结构的顺序表&#xff08;这个之前写过一次&#xff0c;不过本期和之前可能会略有不同&#xff0c;但大体相同&#xff09;&#xff0c;大家可以看一下我们之前完成的顺序表 (6条消息) 顺序表及其多种接口的实现_顺序表类中实现接口方法_KLZUQ的博客-CSDN博客…

Linux环境下验证python项目

公司大佬开发的python rpa跑数项目&#xff0c;Windows运行没问题后&#xff0c;需要搭建一个linux环境进行验证&#xff0c;NOW START&#xff01; Install VMware官网 下载好之后打开按步骤安装 最后一步会让填许可证&#xff08;密钥&#xff09;&#xff0c;这里自行百…

Meta开放小模型LLaMA,性能超过GPT-3

论文地址&#xff1a;https://research.facebook.com/file/1574548786327032/LLaMA--Open-and-Efficient-Foundation-Language-Models.pdf 介绍 LLaMA&#xff0c;是Meta AI最新发布的一个从7B到65B参数的基础语言模型集合。在数以万亿计的token上训练模型&#xff0c;并表明…

运动跑步耳机哪种最好、5款最好用的运动耳机推荐

而作为一名运动爱好者&#xff0c;我非常喜欢在运动时听音乐&#xff0c;简直不要太轻松&#xff01;不过在换了多款蓝牙耳机之后&#xff0c;我终于找到了几款非常适合运动的耳机&#xff0c;戴着它们运动&#xff0c;不仅不会出现不适感&#xff0c;还能享受清晰动听音乐&…

多个AOP修饰同一个方法

1、背景 之前的文章中&#xff0c;有网友提出了一个问题&#xff0c;同一个方法用多个AOP修饰&#xff0c;执行顺序是怎样的&#xff1f; 好问题&#xff0c;之前没有关注过&#xff0c;这里写一个demo跑一下看看 同时有一个衍生问题&#xff0c;多个AOP修饰&#xff0c;会生…