算法训练day42leetcode01背包问题 416. 分割等和子集

01 背包

题目描述

有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

题目分析

每一件物品其实只有两个状态,取或者不取,所以可以使用回溯法搜索出所有的情况,那么时间复杂度就是$o(2^n)$,这里的n表示物品数量。

所以暴力的解法是指数级别的时间复杂度。进而才需要动态规划的解法来进行优化!

  1. 确定递推公式

再回顾一下dp[i][j]的含义:从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。

那么可以有两个方向推出来dp[i][j],

  • 不放物品i:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。)
  • 放物品i:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值

所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

数据结构:

  • weight:一个向量,包含各个物品的重量。
  • value:一个向量,包含各个物品的价值。
  • bagweight:一个整数,代表背包的总容量。
  • dp:一个2D向量,其中dp[i][j]表示用前i个物品填充容量为j的背包时可以达到的最大价值。

算法步骤:

  1. 初始化:首先,使用物品0初始化dp数组的第一行。如果背包的容量大于等于物品0的重量,则背包可以装下物品0,所以对所有的j >= weight[0]dp[0][j]的值被设置为物品0的价值。
  2. 填充DP表:接下来,遍历每个物品(除了第一个已经处理过的物品),并对每个可能的背包容量进行考虑。对于每个物品i和每个容量j
    • 如果当前背包容量j小于物品i的重量,则无法包含当前物品,因此dp[i][j]的值就是不包含当前物品时的最大价值,即dp[i-1][j]
    • 如果当前背包容量可以容纳物品i,则需要决定是包含还是不包含当前物品以达到最大价值。这通过比较不包含当前物品(dp[i-1][j])和包含当前物品(dp[i-1][j-weight[i]] + value[i])时的价值来决定。选择这两种情况中的最大值作为dp[i][j]的值。

输出:

  • 通过查看dp数组的最后一个元素dp[weight.size() - 1][bagweight],可以得到使用给定物品填充指定容量背包的最大价值。

这种动态规划方法有效地解决了0/1背包问题,通过构建一个解决方案的表格,使得可以通过较小的子问题的解来构建出整个问题的解,从而避免了冗余的计算和指数级的复杂度。

acm模式代码

#include <iostream>
#include <vector>
using namespace std;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 = 0 ; j < weight[0]; j++) {  // 当然这一步,如果把dp数组预先初始化为0了,这一步就可以省略,但很多同学应该没有想清楚这一点。dp[0][j] = 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();
}

01背包一维

 题目分析

其实可以发现如果把dp[i - 1]那一层拷贝到dp[i]上,表达式完全可以是:dp[i][j] = max(dp[i][j], dp[i][j - weight[i]] + value[i]);

dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

关于初始化,一定要和dp数组的定义吻合,否则到递推公式的时候就会越来越乱

这样才能让dp数组在递归公式的过程中取的最大的价值,而不是被初始值覆盖了

所以一维dp数组的背包在遍历顺序上和二维其实是有很大差异的!

acm模式代码

#include <iostream>
#include <vector>void test_1_wei_bag_problem() {std::vector<int> weight = {1,3,4};std::vector<int> value = {15, 20 ,30};int bagweight = 4;//初始化std::vector<int> dp(bagweight + 1, 0);for (int i = 0; i < weight.size(); i++) {for (int j = bagweight;j >= weight[i]; j--) {dp[j] = std::max(dp[j], dp[j - weight[i]] + value[i]);}}std::cout << dp[bagweight] << std::endl;
}int main() {test_1_wei_bag_problem();
}

416. 分割等和子集

题目描述

给你一个 只包含正整数 的 非空 数组 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

acm模式代码


#include <iostream>
#include <vector>
using namespace std;class Solution {
public:bool canPartition(vector<int>& nums) {int sum = 0;for (int num : nums) {sum += num;}if (sum % 2 != 0) return false; // Early return if the sum is odd.int target = sum / 2;vector<bool> dp(target + 1, false);dp[0] = true; // Base case: zero sum is always possible.for (int num : nums) {for (int j = target; j >= num; j--) {dp[j] = dp[j] || dp[j - num];}}return dp[target];}
};int main() {Solution sol;vector<int> nums = {1, 5, 11, 5}; // Example inputbool canPart = sol.canPartition(nums);if(canPart) {cout << "Can partition: YES" << endl;} else {cout << "Can partition: NO" << endl;}return 0;
}

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

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

相关文章

CNC机加工引入复合机器人可以提高生产效率,降低成本

CNC加工企业在过去依赖大量的人工来完成生产线上的各项任务&#xff0c;包括CNC机床的上下料、物料搬运以及部分装配工作。然而&#xff0c;随着产能需求的不断增长和人工成本的持续上升&#xff0c;企业逐渐意识到自动化升级的重要性与迫切性。 面临的挑战与需求&#xff1a; …

Layer1 新星 Partisia Blockchain 撑起隐私保护伞,助你无忧加密交易!

信息纷繁芜杂、真假掺半的 Web3 行业&#xff0c;如何才能更快、更安全地实现快速交易&#xff1f;Partisia Blockchain 或许交出了一份满意的技术答卷。致力于隐私保护、互操作性和可持续创新的 Layer1 区块链新星&#xff0c;Partisia Blockchain 以安全公平标榜&#xff0c;…

VScode(Python)使用ssh远程开发(Linux系统树莓派)时,配置falke8和yapf总结避坑!最详细,一步到位!

写在前面&#xff1a;在Windows系统下使用VScode时可以很舒服的使用flake8和yapf&#xff0c;但是在ssh远程开发树莓派时&#xff0c;我却用不了&#xff0c;总是出现问题。当时我就开始了漫长的探索求知之路。中间也请教过许多大佬&#xff0c;但是他们就讲“能用不就行了&…

Jeff Bezos的投资正开始见效

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Vue+wow.js+animate.css实现动画效果

1.介绍 Wow.js 是一个轻量级的 JavaScript 库&#xff0c;用于在网页滚动时实现动画效果。基于 CSS3 的动画库 Animate.css&#xff0c;并通过触发 CSS 动画类来创建各种引人注目的过渡和动画效果。 使用 Wow.js&#xff0c;可以很容易地为网页中的元素添加动画效果&#xff…

MVC架构模式学习笔记(动力节点老杜2022)

GitHub代码笔记&#xff1a;laodu-mvc: 动力节点学习javaweb中的mvc笔记。 文章目录 1.视频链接 2.不使用MVC架构模式程序存在的缺陷 3.MVC架构模式理论基础 4.JavaEE设计模式-DAO模式 5.pojo & bean & domain 6.业务层抽取以及业务类实现 7.控制层 8.MVC架构模式与三…

Android apk 打包及签名

Android apk打包及签名主要分为3步&#xff1a; 1. 生成签名key store ➜ ~ keytool -genkey -v -keystore meet.jks -alias meet -keyalg RSA -keysize 2048 -validity 10000 keytool参数详解&#xff1a; -genkey&#xff1a;指示keytool生成一个新的密钥对。 -v&#xff…

Mac中文输入法区分回车和提交

一、功能描述&#xff1a; 在搜索框中输入关键词&#xff0c;回车跳转至搜索结果页 二、项目背景记录&#xff1a; vue3vuetify的项目 三、问题描述&#xff1a; 中文输入法。 在Windows下输入拼音后&#xff0c;敲击空格 > 显示第一个联想词&#xff0c;敲击回车 > 拼…

Python中的列表推导式是什么,并给出一个例子?

Python中的列表推导式&#xff08;List Comprehension&#xff09;是一种优雅且简洁的方式&#xff0c;用于快速生成列表。它是Python迭代机制的一种扩展&#xff0c;允许你使用一行代码就能根据已有的列表或可迭代对象&#xff08;如元组、字符串、集合等&#xff09;创建新的…

ElasticSearch之Nested对象

写在前面 本文看下es的nested嵌套对象相关内容。 1&#xff1a;es用了啥范式&#xff1f; 在关系型数据库中定义了6大数据库范式,即1&#xff0c;2&#xff0c;3&#xff0c;BC&#xff0c;4&#xff0c;5的NF&#xff08;normal form&#xff09;,分别如下&#xff1a; 1N…

学习编程为什么选择C/C++,那么C++的强大之处到底体现在哪里呢?

学习编程为什么选择C/C&#xff0c;那么C的强大之处到底体现在哪里呢&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共…

Retelling|Facebook1

录音 Facebook 1 Retelling|Facebook1 复述转写 Today Im totally going to talk about Facebook. The aspects of this (its)rising fame and fortune, and the rise (小停顿)in(rising) fame and fortune of s founder Mark Zuckerberg, Mark Zuckerberg created this plat…

ctf_show笔记篇(web入门---代码审计)

301&#xff1a;多种方式进入 从index.php页面来看 只需要访问index.php时session[login]不为空就能访问 那么就在访问index.php的时候上传login 随机一个东西就能进去从checklogin页面来看sql注入没有任何过滤 直接联合绕过 密码随意 还有多种方式可以自己去看代码分析 30…

力扣串题:字符串中的第二大数字

此题的精妙之处在于char类型到int类型的转化&#xff0c;需要运算来解决 int secondHighest(char * s) {int max1-1;int max2-1;int szstrlen(s);int i 0 ;for(i0;i<sz;i){if(s[i]>0&&s[i]<9){if((s[i]-0)>max1){max2max1;max1s[i]-0;}else if((s[i]-0)&l…

峟思仪器助力尾矿库安全监测

在矿业领域&#xff0c;尾矿库的安全监测是保障矿山持续、安全运营的关键环节。尾矿库通常用于存放矿山开采过程中产生的固体废物&#xff0c;如果管理不善&#xff0c;可能会造成重大的安全事故&#xff0c;对环境和人类健康造成严重威胁。因此&#xff0c;采用先进的监测技术…

Sqllab第一关通关笔记

知识点&#xff1a; 明白数值注入和字符注入的区别 数值注入&#xff1a;通过数字运算判断&#xff0c;1/0 1/1 字符注入&#xff1a;通过引号进行判断&#xff0c;奇数个和偶数个单引号进行识别 联合查询&#xff1a;union 或者 union all 需要满足字段数一致&…

SAR洪水检测分析

对于洪水检测,经常使用合成孔径雷达 (SAR) 卫星图像。这里显示了 SAR 图像用于洪水检测的优缺点。 优点: - 无论天气如何,都能够捕获图像,从而实现高时间分辨率。 - 由于镜面反射,很容易区分水和其他物体。 缺点: - 图像中有很多斑点噪声。 - 凭直觉很难理解图像中出现…

机界先锋:Figure 01实现全面沟通与AGI通用人工智能的征途

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

yum安装mysql 数据库tab自动补全

centos7上面没有mysql&#xff0c;它的数据库名字叫做mariadb [rootlocalhost ~]#yum install mariadb-server -y [rootlocalhost ~]#systemctl start mariadb.service [rootlocalhost ~]#systemctl stop firewalld [rootlocalhost ~]#setenforce 0 [rootlocalhost ~]#ss -na…

代码随想录三刷day29

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣455. 分发饼干二、力扣376. 摆动序列三、力扣53. 最大子数组和 前言 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 一、力扣45…