代码随想录算法训练营第42天| 背包问题、416. 分割等和子集

01 背包

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

二维dp数组01背包

  1. 确定dp数组以及下标的含义
    对于背包问题,有一种写法, 是使用二维数组,即dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

在这里插入图片描述

  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]);

  2. 初始化
    dp[i][j]是由其左侧和左上方数据推导出来的,因此要初始化dp[i][0]列和dp[0][j]行的数据,背包重量为0时,背包内物品的价值为零,dp[i][0]列为0。dp[0][i]行的数据,当背包容量j≥wieght[j]时,dp[0][j]=value[j],其他时候为零。

  3. 遍历顺序
    先遍历还是weight还是value都可以。

#include<iostream>
#include<vector>
using namespace std;void slove(int m, int n){vector<int> wight;vector<int> value;int x;for (int i = 0; i < m;i++){cin>>x;wight.push_back(x);}for (int i = 0; i < m;i++){cin>>x;value.push_back(x);}vector<vector<int>> dp(m,vector<int>(n+1,0));for(int j = 0; j <= n; j++){if(j>=wight[0]){dp[0][j] = value[0];}}for (int i = 1; i < m; i++){for (int j = 1; j <= n; j++){if(j < wight[i]){dp[i][j] = dp[i-1][j];} else {dp[i][j] = max(dp[i-1][j], dp[i-1][j-wight[i]]+value[i]);}}}cout << dp[m-1][n] <<endl;
}int main(){int m,n;cin>>m>>n;slove(m,n);
}

一维dp数组01背包

对于背包问题其实状态都是可以压缩的。

在使用二维数组的时候,递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

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

与其把dp[i - 1]这一层拷贝到dp[i]上,不如只用一个一维数组了,只用dp[j](一维数组,也可以理解是一个滚动数组)。

但是这里要注意,dp数组的遍历要为倒序遍历,倒序遍历是为了保证物品i只被放入一次!。但如果一旦正序遍历了,那么物品0就会被重复加入多次!

#include<iostream>
#include<vector>
using namespace std;void slove(int m, int n){vector<int> wight;vector<int> value;int x;for (int i = 0; i < m;i++){cin>>x;wight.push_back(x);}for (int i = 0; i < m;i++){cin>>x;value.push_back(x);}vector<int> dp(n+1,0);for (int i = 0; i < m; i++){for (int j = n; j >= 0; j--){if(j >= wight[i]){dp[j] = max(dp[j], dp[j-wight[i]]+value[i]);}}}cout << dp[n] <<endl;
}int main(){int m,n;cin>>m>>n;slove(m,n);
}

416. 分割等和子集

题目链接:分割等和子集

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

解题思想:

要明确本题中我们要使用的是01背包,因为元素我们只能用一次。

回归主题:首先,本题要求集合里能否出现总和为 sum / 2 的子集。

那么来一一对应一下本题,看看背包问题如何来解决。

只有确定了如下四点,才能把01背包问题套到本题上来。

  • 背包的体积为sum / 2
  • 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
  • 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
  • 背包中每一个元素是不可重复放入。

后面的解题思路就和01背包问题相同

class Solution {
public:bool canPartition(vector<int>& nums) {int sum = 0;int target = 0;for (int num : nums)sum += num;if (sum % 2)return false;elsetarget = sum / 2;vector<int> dp(target + 1, 0);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;}
};

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

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

相关文章

实景三维技术也是一种新质生产力

实景三维技术作为一种新兴的技术手段&#xff0c;正在逐渐被认为是一种新质生产力。它通过高精度的数据采集、处理和可视化&#xff0c;为多个行业领域提供了全新的工作方式和解决方案&#xff0c;从而推动了生产力的发展和创新。以下是实景三维技术作为新质生产力在不同方面的…

2024年华为OD机试真题-最长的指定瑕疵度的元音子串-Java-OD统一考试(C卷)

题目描述: 开头和结尾都是元音字母(aeiouAEIOU)的字符串为 元音字符串 ,其中混杂的非元音字母数量为其 瑕疵度 。比如: “a” 、 “aa”是元音字符串,其瑕疵度都为0 “aiur”不是元音字符串(结尾不是元音字符) “abira”是元音字符串,其瑕疵…

Mac 配置 Aria2

文章目录 1. Aria2 安装1.1 安装 brew1.2 安装 Aria2 2. 配置 Aria22.1 创建配置文件 aria2.conf 和空对话文件 aria2.session2.2 编辑配置文件 aria2.conf 3. 开机启动设置3.1 创建用户启动文件3.2 管理自启动项 4. 配置 BT tracker 自动更新4.1 XIU2/TrackersListCollection …

通义灵码-ai编码

https://developer.aliyun.com/topic/lingma/activities/202403?taskCode14508&recordIdb1ef3ba27250a5818b1b6ffe418af658#/?utm_contentm_fission_1 「通义灵码 体验 AI 编码&#xff0c;开 AI 盲盒」

Python笔记|列表推导式

用列表推导式创建列表的方式更简洁。常见的用法为&#xff0c;对序列或可迭代对象中的每个元素应用某种操作&#xff0c;用生成的结果创建新的列表&#xff1b;或用满足特定条件的元素创建子序列。 例如&#xff0c;创建平方值的列表&#xff1a; >>> squares [] &…

【Kafka】Kafka安装、配置、使用

【Kafka】安装Kafka 1. 安装Kafka2. Kafka使用2.0 集群分发脚本xsync(重要)2.0.1 scp命令2.0.2 rsync远程同步工具2.0.3 写一个集群分发脚本xsync (Shell 脚本) 2.1 Zookeeper安装2.2 对Kafka进行分发2.2.1 执行同步脚本2.2.2 三台云主机配置Kafka环境变量 1. 安装Kafka Kafka…

《QT实用小工具·十五》多种样式的开关控件

1、概述 源码放在文章末尾 目前实现了三种样式的开关控件按钮&#xff0c;如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #ifndef IMAGESWITCH_H #define IMAGESWITCH_H/*** 图片开关控件 * 1. 自带三种开关按钮样式。* 2. 可自定义开关图片。*/#include <QWid…

多層解壓p

import os import subprocess from tqdm import tqdm def extract_compressed_file(file_path, passwordNone, extract_path"."):"""解压单个压缩文件到指定目录&#xff0c;并实时显示解压进度Parameters:- file_path (str): 压缩文件的完整路径- pa…

FreeRtos入门-7 中断管理

中断管理 中断管理相比非中断的优势 1&#xff0c;简洁和效率。 2&#xff0c;同步和安全。提供了中断安全的操作&#xff0c;确保在中断上下文中执行时不会引发竞态条件或破坏系统状态。 3&#xff0c;通过配置中断的优先级&#xff0c;可以确保高优先级的中断能够立即响应…

配置Mysql集群主从复制报错

配置Mysql集群主从复制报错: 我在master创建了一个数据库&#xff08;demo_ds_0&#xff09;,然后又快速删除了。然后又再次创建了 demo_ds_0, 发现 slave 数据库没有将 demo_ds_0 库同步过来。 后面在 slave 数据库中执行 show slave status 发现 SLave_IO_Running 字段是 …

浏览器控制台(console)中JS的常用方法:获取元素、鼠标点击、键盘输入等

文章目录 1.获取元素的常用方法(1)获取tabs列表(国内版/国际版)2.模拟输入框input的输入3.模拟点击click()1.获取元素的常用方法 // 1 根据元素IDlet img = document.getElementById("m1");// 2 根据元素标签--元素列表let div

OpenHarmony开发-系统烧录

本文详细介绍了烧录OpenHarmony系统到开发板的操作流程。从基础的硬件准备和软件环境设置入手&#xff0c;详细说明了如何配置开发环境、构建系统镜像等过程&#xff0c;详细描述了烧录过程中的关键步骤&#xff0c;以及如何使用专用工具将OpenHarmony系统镜像传输到开发板。同…

蓝桥杯每日一题:公约数(gcd)

题目描述&#xff1a; 给定两个正整数 a 和 b。 你需要回答 q 个询问。 每个询问给定两个整数 l,r&#xff0c;你需要找到最大的整数 x&#xff0c;满足&#xff1a; x 是 a和 b 的公约数。l≤x≤r。 输入格式 第一行包含两个整数 a,b。 第二行包含一个整数 q。 接下来…

力扣Lc29---- 541. 反转字符串 II(java版)-2024年4月06日

1.题目描述 2.知识点 &#xff08;1&#xff09;执行步骤如下&#xff1a; 初始化 s “abcdefg” 和 k 2 将字符串分割成长度为 2k 4 的块。 对每个块中的前 k 2 个字符进行反转。 执行过程 1&#xff09;第一次循环&#xff08;i 0&#xff09; start 0 end Math.min(0…

当下鸿蒙开发热潮,大前端开发有没有必要搞!!!

鸿蒙到底好不好&#xff1f;要不要搞&#xff1f; Android开发反正目前工作感觉也不好找&#xff0c;即便是上海这样的大城市也难搞&#xff0c;人员挺饱和的。而且年前裁员的公司那么多&#xff0c;再看自己&#xff0c;年龄不是优势&#xff1b;技术不是优势&#xff0c;想想…

前端进阶特训营-班会

程邵非(winter):javascript专家 夏然(全栈然叔):Vue3.0 工程化--大项目&#xff0c;工程化有专门团队。 杨涛(村长):Vue3.0 架构师 高少云(bubucuo):React18 课程设计 1.前端基础-程邵非 建立前端体系架构 重新理解JS&#xff0c;CSS&#xff0c;HTML的底层原理 理解前端工程师…

16 - 程序计数器和内存

---- 整理自B站UP主 踌躇月光 的视频 1. 程序计数器 程序计数器需要支持后续程序的运行&#xff0c;需要支持跳转&#xff0c;所以需要一个预置数的功能。我们在 ALU 前面加上个寄存器。 2. 内存控制器 3. 通过程序计数器读取内存 辅助工具 4. 实验工程 【16 - 程序计数器和…

【C++】红黑树讲解及实现

前言&#xff1a; AVL树与红黑树相似&#xff0c;都是一种平衡二叉搜索树&#xff0c;但是AVL树的平衡要求太严格&#xff0c;如果要对AVL树做一些结构修改的操作性能会非常低下&#xff0c;比如&#xff1a;插入时要维护其绝对平衡&#xff0c;旋转的次数比较多&#xff0c;更…

降低笔记本电脑噪音的七种方法,看下有没有适合你的

序言 无论是玩游戏、浏览网络还是做严肃的工作,差不多都有这么一台笔记本电脑,它有足够的处理能力来处理几乎任何事情。不幸的是,它可能会变得非常大声,但有办法来遏制这种噪音。 清洁通风口和风扇,并使用硬表面 如果你的笔记本电脑现在比过去运行同样的软件时声音更大…

继承 多态 向上转型 向下转型

一、什么是继承 继承就是子类继承父类的特征和行为&#xff0c;使得子类对象&#xff08;实例&#xff09;具有父类的实例域和方法&#xff0c;或子类从父类继承方法&#xff0c;使得子类具有父类相同的行为。当然&#xff0c;如果在父类中拥有私有属性(private修饰)&#xff…