代码随想录算法训练营第42天 | 01背包理论基础 416.分割等和子集

01背包理论基础

  • 问题定义:有n件物品和一个能装重量为w的背包,第i件物品的重量是weight[i],得到的价值是value[i]。每件物品只能用一次,求解将哪些物品装入背包获得的总价值最大。
  • dp数组含义:dp[i][j] 表示从下标为 [0,i] 的物品中选,放进容量为j的背包中,能得到的最大价值总和。
  • 确定递推公式:在推导 dp[i][j] 时有两个方面:一是不放物品i,因为不放i物品,所以dp[i][j] = dp[i - 1][j],是只放前 i-1 个物品时的最大值;二是放物品i,dp[i][j] = dp[i - 1][j - weight[i]] + value[i]。当背包容量小于i号物品重量时赋值第一方面的值,否则赋值为两种情况的最大值。
  • 确定初始化:dp[i][0] 由于背包容量为0,根本放不进物品,所以初始化为0。dp[0][j] 只放0号物品,当 j >= weight[0] 时有值value[0],其他情况为0。
  • 遍历顺序:这是重点,要决定当前的状态,必须由其左上角的状态决定。先遍历物品还是先背包容量都是可以的。
#include <bits/stdc++.h>
using namespace std;
int n, 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 i = 0; i < n; i++) {
		cin >> value[i];
	}
	vector<vector<int>> dp(n, vector<int>(bagweight + 1, 0));
	for(int i = weight[0]; i <= bagweight; i++) {  // 初始化
		dp[0][i] = value[0];
	}
	for(int i = 1; i < n; i++) {
		for(int j = 1; 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[n - 1][bagweight] << endl;
}
int main() {
	while(cin >> n >> bagweight) {
		solve();
	}
	return 0;
}

滚动数组空间优化

我们观察二维数组的递推式,可以发现 dp[i][j] 只与 i - 1 那一层的状态有关。因此可以用一个一维数组来表示状态。

  • dp[j] 表示容量为 j 的背包能获得的最大价值总和。
  • 因为在当前遍历过程中 dp 中存储的就是上一层的状态,因此状态递推式为
    dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
  • 初始化:下标0位置一定初始化为0,其他位置为了递推式中的取最大值服务,也初始化为0即可。
  • 遍历顺序背包容量的遍历需要从大到小,倒序遍历是为了保证物品i只被放入一次。当前遍历中未处理的部分都是i-1那一层的值,因此只有倒序遍历才能保证用到的状态没用过物品i。另一方面,我们更新状态需要知道当前位置左侧的i-1状态 (j-weight[i]),正序遍历就让左侧的状态变成当前层的。
#include <bits/stdc++.h>
using namespace std;
int main() {
	int n, bagweight;
	while(cin >> n >> bagweight) {
		vector<int> weight(n, 0);
		vector<int> value(n, 0);
		for(int i = 0; i < n; i++) {
			cin >> weight[i];
		}
		for(int i = 0; i < n; i++) {
			cin >> value[i];
		}
		vector<int> dp(bagweight + 1, 0);
		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;
	}
	return 0;
}

分割等和子集

Alt
其实用回溯可解,但是会超时。因为每一个元素只能用一次,考虑01背包试一下。
背包的大小为 sum / 2,每一个元素看做物品,其重量为元素值,价值也为元素值。问题就转换成在sum / 2的背包中放入元素,让背包尽可能的满,由于重量等于价值,就变成让价值总和尽量大,最终查看最大值是否与sum / 2相等,就能判断能不能分割。

class Solution{
public:
	bool canPartition(vector<int>& nums) {
		int sum = 0;
		for(int num : nums) {
			sum += num;
		}
		if(sum % 2)  return false;  // 和为奇数,不可能分成相等的两份
		int target = 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]);
			}
		}
		return dp[target] == target;
	}
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springboot基础案例(二)

文章目录 前言一.需求分析: 分析这个项目含有哪些功能模块二.库表设计(概要设计): 1.分析系统有哪些表 2.分析表与表关系 3.确定表中字段(显性字段 隐性字段(业务字段))2.1 创建一个库: ems-thymeleaf2.2 创建 2张表三.编码(环境搭建)1.创建一个springboot项目 项目名字: ems-t…

Ubuntu环境下安装部署Nginx(有网)

本文档适用于在Ubuntu20.04系统下部署nginx 一、使用apt-get命令安装nginx 注&#xff1a;以下命令都是在root用户下使用 1. 检查是否存在apt命令 apt –version 说明&#xff1a;出现版本号就说明当前环境存在apt 2. 更新apt命令 apt update 3. 安装nginx apt-get in…

【保姆级教程|YOLOv8改进】【7】多尺度空洞注意力(MSDA),DilateFormer实现暴力涨点

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

Minecraft 上 An Existing Connection Was Forcibly Closed by the Remote Host 错误

本篇文章介绍了使用 Minecraft 时出现远程主机错误强制关闭现有连接的原因和解决方案。 Minecraft 上 Java.IO.IOException: An Existing Connection Was Forcibly Closed by the Remote Host 原因 Minecraft 是一款使用 Java 开发的流行游戏。 由于其流行&#xff0c;服务器…

jxls 2.4.5 —— 动态导出excel 表头与数据

文章目录 前言依赖引入制作导出模板测试类导出效果注意事项 前言 再之前的博客中&#xff0c;介绍了jxls的基础使用。但导出表头属于写死的&#xff0c;并未采取动态渲染。 本次进行动态渲染操作&#xff0c;动态渲染表头和填充数据。 依赖引入 springboot测试项目中&#…

AdaBoost算法

Boosting是一种集成学习方法&#xff0c;AdaBoost是Boosting算法中的一种具体实现。 Boosting方法的核心思想在于将多个弱分类器组合成一个强分类器。这些弱分类器通常是简单的模型&#xff0c;比如决策树&#xff0c;它们在训练过程中的错误会被后续的弱分类器所修正。Boosti…

多元回归分析:理论与应用

多元回归分析是一种统计方法&#xff0c;用于研究两个或多个自变量&#xff08;解释变量&#xff09;与一个因变量&#xff08;响应变量&#xff09;之间的关系。这种分析允许研究者评估多个因素对结果变量的影响&#xff0c;是社会科学、经济学、生物医学和工程等多个领域中常…

SolidWorks学习笔记——入门知识1

目录 1、固定最近文档 2、根据需要自定义菜单栏 3、根据需要增添选项卡 4、命令搜索框 5、鼠标右键长按快速切换视图 6、鼠标笔势 自定义鼠标笔势 1、固定最近文档 图1 固定最近文档 2、根据需要自定义菜单栏 图2 根据需要自定义菜单栏 3、根据需要增添选项卡 图3 根据…

Linux介绍和命令使用

目录 目录 一、Linux简介 1.1 主流操作系统 1.2 Linux 发展历史 1.3 Linux系统版本 二、Linux安装 三、Linux 目录结构 四、Linux常用命令 4.1 基础常用命令说明 4.2 Linux 命令使用技巧 4.3 Linux 命令格式 4.4 进阶重点常用命令 4.4.1 拷贝移动命令 4.4.2 打包…

09 AB 10串口通信发送原理

通用异步收发传输器&#xff08; Universal Asynchronous Receiver/Transmitter&#xff0c; UART&#xff09;是一种异步收发传输器&#xff0c;其在数据发送时将并行数据转换成串行数据来传输&#xff0c; 在数据接收时将接收到的串行数据转换成并行数据&#xff0c; 可以实现…

springboot项目热部署实现(Spring Boot DevTools方式)

文章目录 Spring Boot DevTools简介Spring Boot DevTools原理spring Boot Devtools优缺点Spring Boot DevTools集成步骤第一步&#xff1a;添加maven依赖第二步&#xff1a;IDEA热部署配置 Spring Boot DevTools简介 Spring Boot DevTools是Spring Boot提供的一个开发工具&…

二维数组的使用

一、二维数组的使用 动态初始化静态初始化 1、动态初始化 2、静态初始化

【Git版本控制 05】多人协作

目录 一、邀请开发用户 二、新建远程分支 三、拉取远程分支 四、推送远程分支 五、合并远程分支 六、多分支协作 一、邀请开发用户 在windows环境下&#xff0c;再clone同⼀个项⽬仓库&#xff0c;来模拟⼀起协作开发的另⼀名⼩伙伴。 际开发中&#xff0c;每个⽤⼾都有…

【flink状态管理(三)】StateBackend的整体设计、StateBackend创建说明

文章目录 一. 状态后端概述二. StateBackend的整体设计1. 核心功能2. StateBackend的UML3. 小结 三. StateBackend的加载与初始化1. StateBackend创建概述2. StateBackend创建过程 一. 状态后端概述 StateBackend作为状态存储后端&#xff0c;提供了创建和获取KeyedStateBacke…

【51单片机】实现一个动静态数码管显示项目(超全详解&代码&图示)(5)

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY…

vue项目打包部署到flask等后端服务里面,实现前后端不分离部署,解决空白页面和刷新页面not fount问题

1. 编译模式一定要设置为esnext&#xff0c;否则会报错&#xff1a; Strict MIME type checking is enforced for module scripts per HTML spec.Expected a JavaScript module script but the server responded with a MIME type of "text/plain". 具体解释可以看vi…

牛客网SQL进阶127: 月总刷题数和日均刷题数

官网链接&#xff1a; 月总刷题数和日均刷题数_牛客题霸_牛客网现有一张题目练习记录表practice_record&#xff0c;示例内容如下&#xff1a;。题目来自【牛客题霸】https://www.nowcoder.com/practice/f6b4770f453d4163acc419e3d19e6746?tpId240 0 问题描述 基于练习记录表…

PyTorch深度学习实战(23)——从零开始实现SSD目标检测

PyTorch深度学习实战&#xff08;23&#xff09;——从零开始实现SSD目标检测 0. 前言1. SSD 目标检测模型1.1 SSD 网络架构1.2 利用不同网络层执行边界框和类别预测1.3 不同网络层中默认框的尺寸和宽高比1.4 数据准备1.5 模型训练 2. 实现 SSD 目标检测2.1 SSD300 架构2.2 Mul…

深度学习的新进展:解析技术演进与应用前景

深度学习的新进展&#xff1a;解析技术演进与应用前景 深度学习&#xff0c;作为人工智能领域的一颗璀璨明珠&#xff0c;一直以来都在不断刷新我们对技术和未来的认知。随着时间的推移&#xff0c;深度学习不断迎来新的进展&#xff0c;这不仅推动了技术的演进&#xff0c;也…

Vue中路由守卫的详细应用

作为一名web前端开发者&#xff0c;我们肯定经常使用Vue框架来构建我们的项目。而在Vue中&#xff0c;路由是非常重要的一部分&#xff0c;它能够实现页面的跳转和导航&#xff0c;提供更好的用户体验。然而&#xff0c;有时我们需要在路由跳转前或跳转后执行一些特定的逻辑&am…
最新文章