当前位置: 首页 > news >正文

0/1背包问题总结

文章目录

  • 🍇什么是0/1背包问题?
  • 🍈例题
    • 🍉1.分割等和子集
    • 🍉2.目标和
    • 🍉3.最后一块石头的重量Ⅱ
  • 🍊总结

在这里插入图片描述
博客主页:lyyyyrics

🍇什么是0/1背包问题?

0/1背包问题是一个经典的组合优化问题,其描述如下:

假设有一个背包,它能够承载一定的重量。现在有一组物品,每个物品有各自的重量和价值。我们的目标是在不超过背包承载重量的前提下,选择一些物品放入背包中,使得背包中物品的总价值最大化。

具体来说,假设有 n n n个物品,其重量分别为 w 1 , w 2 , . . . , w n w_1, w_2, ..., w_n w1,w2,...,wn,对应的价值分别为 v 1 , v 2 , . . . , v n v_1, v_2, ..., v_n v1,v2,...,vn。背包的承载重量为 W W W。我们需要在这 n n n个物品中选择一些放入背包中,使得这些物品的总重量不超过 W W W,且总价值最大化。

数学公式可以表示为:

Maximize ∑ i = 1 n v i x i subject to ∑ i = 1 n w i x i ≤ W x i ∈ { 0 , 1 } , i = 1 , 2 , . . . , n \begin{align*} \text{Maximize} \quad & \sum_{i=1}^{n} v_ix_i \\ \text{subject to} \quad & \sum_{i=1}^{n} w_ix_i \leq W \\ & x_i \in \{0, 1\}, \quad i=1,2,...,n \end{align*} Maximizesubject toi=1nvixii=1nwixiWxi{0,1},i=1,2,...,n

其中, x i x_i xi表示第 i i i个物品是否放入背包中。若 x i = 1 x_i=1 xi=1,表示放入;若 x i = 0 x_i=0 xi=0,表示不放入。

🍈例题

🍉1.分割等和子集

题目:

在这里插入图片描述

样例输出和输入:

在这里插入图片描述

根据描述,这道题就是让我们求一个数组是否能将其分成两块 ,然后这两块是相等的,如果能返回true,如果不能则返回false。
算法原理:
首先我们注意到,这道题要将数组分成两个部分,这两个部分是否相等,我们可以转化为分成一个部分,这个部分是数组总和的一半?很显然是可以的,这样转换之后其实就已经是背包问题了,这个数组中的数就是物品,数组中的数就代表每个物品的价值,然后数组中的数的总和的一半就是这个背包的容量,问题就 转化为,我们是否可以从数组中挑出一些物品,使得物品的体积恰好能把这个 背包塞满?
状态表示:dp[i][j]表示前i个数中的所有的选法中,是否存在和为j的选法,如果存在则是true,如果不存在则就是false。
状态转移方程:状态转移方程还是考虑i位置和j位置。
在这里插入图片描述
如果能选的话,应该是选和不选中有一个满足就够了,所以这里应该还要取一个||,dp[i][j]=dp[i-1][j]||dp[i-1][j-nums[i]]
初始化:在这里插入图片描述
首先看第一行,从1开始,从0个数中选,和为1的,这种情况是不存在的,所以应该是false,后面的从0个数中选的都是false,,我们来看第一列,从0个数中选和为0,那就是不选,所以为true,从1个数中选和为0,可以不选,也是true,所以我们只需要 初始化第一列,初始化为true。
代码:

class Solution {
public:bool canPartition(vector<int>& nums){int n = nums.size();int sum = 0;//求和for (auto e : nums)sum += e;//如果和是奇数的话直接返回if (sum % 2 == 1)return false;//先定义一个aim表示和的一半int  aim = sum / 2;//创建dp表vector<vector<bool>> dp(n + 1, vector<bool>(aim + 1));//初始化dp表的第一列为true,因为如果和为零的话是有可能的。//如果什么都不选的话,当前和就是0for (int i = 0;i <= n;i++){dp[i][0] = true;}for (int i = 1;i <= n;i++){for (int j = 1;j <= aim;j++){//不选的话就是前一个状态的bool值dp[i][j] = dp[i - 1][j];//如果能选的话,只要有一种满足就表示满足if (j >= nums[i - 1])dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]];}}//返回和为aim的状态return dp[n][aim];}
};

运行结果:
在这里插入图片描述

🍉2.目标和

题目:

在这里插入图片描述

样例输出和输入:

在这里插入图片描述

这道题是给定一个数组,我们可以将数组中数 的符号我们可以随便改,最后串成一个加减法的式子,然后这个式子的值为target即可,这道题当然不是让我们返回true或者false,而是让我们返回方法的总数。
算法原理:
这道题其实我们可以将当中的数划分为两类:
在这里插入图片描述
我们将b规定为负数的绝对值。
所以最后可以得出:在这里插入图片描述
所以我们只需要看这个数组中是否组合能使得这个组合最后的和是a即可。
状态表示:dp[i][j]表示从前i个数中选,所有选法中和为j的方法。
状态转移方程:状态转移方程还是看第i个位置:
在这里插入图片描述
如果能选的话,则方法总数就是选和不选的和:dp[i][j]+=dp[i-1][j-nums[i]],但是有一个条件:j>nums[i]

代码:

class Solution 
{
public:int findTargetSumWays(vector<int>& nums, int target){int n = nums.size();int sum = 0;for (auto e : nums)sum += e;int aim = (sum + target) / 2;if (aim < 0 || (sum + target) % 2 == 1)return 0;vector<vector<int>> dp(n + 1, vector<int>(aim + 1));dp[0][0] = 1;for (int i = 1;i <= n;i++){for (int j = 0;j <= aim;j++){dp[i][j] = dp[i - 1][j];if (j >= nums[i - 1])dp[i][j] += dp[i - 1][j - nums[i - 1]];}}return dp[n][aim];}
};

运行结果:
在这里插入图片描述

🍉3.最后一块石头的重量Ⅱ

题目:

在这里插入图片描述
这道题的题目是“最后一块石头的重量 II”。

样例输出和输入:

在这里插入图片描述

给定一堆石头的重量数组stones,在每一回合中,选出两块石头粉碎,最后剩下的石头的重量可能为:

  1. 如果选出的两块石头重量相等,那么两块石头都会被完全粉碎;
  2. 如果选出的两块石头重量不相等,重量为较小的石头将会完全粉碎,而重量为较大的石头新重量为较大石头的重量减去较小石头的重量。

问题要求找到最后剩下的石头的最小可能重量。如果没有剩下的石头,返回0。给定一堆石头的重量数组stones,在每一回合中,选出两块石头粉碎,最后剩下的石头的重量可能为:

  1. 如果选出的两块石头重量相等,那么两块石头都会被完全粉碎;
  2. 如果选出的两块石头重量不相等,重量为较小的石头将会完全粉碎,而重量为较大的石头新重量为较大石头的重量减去较小石头的重量。

问题要求找到最后剩下的石头的最小可能重量。如果没有剩下的石头,返回0。

算法原理:

首先我们模拟一遍这个过程:
在这里插入图片描述

注意:上述过程是建立在前一个比后一个大的基础上模拟的
我们可以发现:当中的数也是有正有负,相当与也可以分成两个分类,一个正一个负:
在这里插入图片描述
在这里插入图片描述
其实我们不难看出,当a和b最接近的时候,这时候差值最小,所以这道题我们就可以转换成了0/1背包问题:
相当于a和b都接近于sum/2,所以这道题的背包容量是sum/2,
状态表示:dp[i][j]表示前i个物品中选,总和不超过j的,最大的和。
状态转移方程:在这里插入图片描述
当存在第一种情况的是否需要和不选的情况求一个最大值:dp[i][j]=max(dp[i-1][j],dp[i-1][j-stones[i]]+stones[i]
代码:

int lastStoneWeightII(vector<int>& stones)
{int n = stones.size();int sum = 0;for (auto e : stones)sum += e;vector<vector<int>> dp(n + 1, vector<int>(sum / 2 + 1));for (int i = 1;i <= n;i++){for (int j = 1;j <= sum / 2;j++){dp[i][j] = dp[i - 1][j];if (j >= stones[i - 1])dp[i][j] = max(dp[i - 1][j - stones[i - 1]] + stones[i - 1], dp[i - 1][j]);}}int a = dp[n][sum / 2];int b = sum - a;return abs(a - b);
}

空间优化过的代码:二维---->一维

class Solution {
public:int lastStoneWeightII(vector<int>& stones){int n = stones.size();int sum = 0;for (auto e : stones)sum += e;vector<int> dp(sum / 2 + 1);for (int i = 1;i <= n;i++)for (int j = sum / 2;j >= stones[i - 1];j--)dp[j] = max(dp[j - stones[i - 1]] + stones[i - 1], dp[j]);int a = dp[sum / 2];int b = sum - a;return abs(a - b);}
};

运行结果:

在这里插入图片描述

🍊总结

0/1 背包问题是组合优化中的经典问题,通过研究和解决这一问题,可以深入理解动态规划的基本思想和应用。本文详细介绍了0/1背包问题的定义、数学模型及其动态规划解法,并通过C++代码示例展示了具体的实现步骤。

通过本次总结,希望读者能够掌握如何将理论知识应用于实际问题,理解状态转移方程的推导过程,以及如何优化算法以提升效率。背包问题不仅在学术研究中具有重要意义,还广泛应用于资源分配、项目管理等实际领域。掌握这一问题的解决方法,可以为解决更复杂的优化问题打下坚实的基础。

在今后的学习中,建议读者多多练习不同变种的背包问题,如完全背包、多重背包问题等,以进一步提升自己的算法设计和分析能力。感谢阅读,希望本文对你的学习和应用有所帮助。

相关文章:

0/1背包问题总结

文章目录 &#x1f347;什么是0/1背包问题&#xff1f;&#x1f348;例题&#x1f349;1.分割等和子集&#x1f349;2.目标和&#x1f349;3.最后一块石头的重量Ⅱ &#x1f34a;总结 博客主页&#xff1a;lyyyyrics &#x1f347;什么是0/1背包问题&#xff1f; 0/1背包问题是…...

模电基础 - 放大电路的频率响应

目录 一. 简介 二. 频率响应的基本概念 三. 波特图 四. 晶体管的高频等效模型 五. 场效应管的高频等效模型 六. 单管放大电路的频率响应 七.多级放大电路的频率响应 八. 频率响应与阶跃响应 一. 简介 放大电路的频率响应是指在输入不同频率的正弦信号时&#xff0c;电路…...

Java 8 到 Java 22 新特性详解

Java 8 到 Java 22 新特性详解 Java自发布以来一直在不断演进&#xff0c;添加新特性以提升开发效率和性能。本文将介绍Java 8到Java 22的主要新特性&#xff0c;帮助开发者了解各版本的新功能和改进。 Java 8 (2014) 1. Lambda 表达式 Lambda 表达式允许使用简洁的语法定义…...

华为OD机试题-提取字符串中最长数学表达式

题目描述 https://blog.csdn.net/weixin_51055612/article/details/139841128 题目描述 提取字符串中的最长合法简单数学表达式&#xff0c;字符串长度最长的&#xff0c;并计算表达式的值。如果没有&#xff0c;则返回0。 简单数学表达式只能包含以下内容&#xff1a;0-9数字&…...

专家指南:如何为您的电路选择理想的压敏电阻或热敏电阻

保护和维持电路功能需要两种设备&#xff1a;压敏电阻和热敏电阻。这两个电气元件有时会因后缀相似而混淆&#xff0c;但它们具有不同且重要的用途。 由于这种混淆&#xff0c;我们需要准确地了解这些组件是什么&#xff0c;这就是本文将要讨论的内容——应用程序、作用、优点…...

基于主流SpringBoot进行JavaWeb开发的学习路线

目录 一、学习路线 &#xff08;1&#xff09;第一部分&#xff08;Web前端开发的技术栈&#xff09; &#xff08;2&#xff09;第二部分&#xff08;Web后端开发&#xff09; 二、学习之后必备的技能 三、学习Web开发的基础与未来的收获 学完这一类知识目标&#xff1a;…...

医疗机器人中的具身智能进展——自主超声策略模型的任务编码和局部探索

医疗机器人一直是具身智能的研究热点。医学图像、医疗触诊、血压血氧、心率脉搏和生物电信号等多模态生物医学信息&#xff0c;不断丰富着医疗机器人的感知范畴。 自主超声 “自主超声”属于具身智能医疗机器人领域中话题度较高的研究方向。作为临床检查的重要手段之一&#…...

探索人工智能在电子商务平台与游戏发行商竞争中几种应用方式

过去 12 年来&#xff0c;电脑和视频游戏的发行策略发生了巨大变化。数字游戏的销量首次超过实体游戏的销量 在20132020 年的封锁进一步加速了这一趋势。例如&#xff0c;在意大利&#xff0c;封锁的第一周导致数字游戏下载量 暴涨174.9%. 展望未来&#xff0c;市场有望继续增…...

【Altium】AD-网络版一个用户非人为异常占用多个License的解决方法

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 当出现一个用户同时占用多个授权&#xff0c;又无法单独释放一个授权的情况下&#xff0c;该如何解决。 2、 问题场景 一个用户获取网络版授权后&#xff0c;AD会自动重复获取授权&#xff0c;直到该license下所有授…...

*算法训练(leetcode)第二十五天 | 134. 加油站、135. 分发糖果、860. 柠檬水找零、406. 根据身高重建队列

刷题记录 134. 加油站135. 分发糖果860. 柠檬水找零406. 根据身高重建队列 134. 加油站 leetcode题目地址 记录全局剩余油量和当前剩余油量&#xff0c;当前剩余小于0时&#xff0c;其实位置是当前位置的后一个位置。若全局剩余油量为负&#xff0c;则说明整体油量不足以走完…...

乐鑫ESPC3 ESP8685 WiFi蓝牙模块透传程序设置教程,抛开繁琐AT指令,简单Web页面配置,即可实现透传

完整文档请下载规格书 TTL-WiFi 透传产品 使用手册 一. 产品概述 二. 接口定义 三. 软件透传WEB配置使用说明 3.1 STATUS配置界面 3.2 MODULE配置界面 n Serial&#xff08;串口配置&#xff09; n WiFi&#xff08;WiFi配置&#xff09; n Networks&#xff08;网络…...

怎么样才能为公司申请OV证书?

OV证书&#xff0c;全称为组织验证型SSL证书&#xff08;Organization Validation SSL Certificate&#xff09;&#xff0c;是一种高级别的SSL/TLS证书&#xff0c;用于加密网站通信并验证网站所属组织的合法身份。相比于基本的域名验证型证书&#xff08;DV证书&#xff09;&…...

Python的`queue`模块

队列&#xff08;Queue&#xff09; 在Python的queue模块中&#xff0c;Queue类是一个线程安全的队列实现&#xff0c;用于在多线程编程中安全地交换信息。它遵循先入先出&#xff08;FIFO&#xff09;的原则。Queue类提供了几种主要的方法&#xff1a; put(item): 将一个项目…...

牛客周赛 Round 50

A题&#xff1a;小红的最小最大 思路&#xff1a; 大水题 code&#xff1a; inline void solve() {int a, b, c; cin >> a >> b >> c;if (min(a, b) c > max(a, b)) cout << "YES\n";else cout << "NO\n";return; }…...

后端之路——登录校验

前言&#xff1a;Servlet 【登录校验】这个功能技术的基础是【会话技术】&#xff0c;那么在讲【会话技术】的时候必然要谈到【Cookie】和【Session】这两个东西&#xff0c;那么在这之前必须要先讲一下一个很重要但是很多人都会忽略的一个知识点&#xff1a;【Servlet】 什么是…...

无线网卡怎么连接台式电脑?让上网更便捷!

随着无线网络的普及&#xff0c;越来越多的台式电脑用户希望通过无线网卡连接到互联网。无线网卡为台式电脑提供了无线连接的便利性&#xff0c;避免了有线网络的束缚。本文将详细介绍无线网卡怎么连接台式电脑的四种方法&#xff0c;包括使用USB无线网卡、内置无线网卡以及使用…...

【45 Pandas+Pyecharts | 去哪儿海南旅游攻略数据分析可视化】

文章目录 &#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. Pandas数据处理2.1 读取数据2.2 查看数据信息2.3 日期处理&#xff0c;提取年份、月份2.4 经费处理2.5 天数处理 &#x1f3f3;️‍&#x1f308; 3. Pyecharts数据可视化3.1 出发日期_…...

Vue3项目给ElementPlus设置中文的两个方案

介绍 在Vue3项目将ElementPlus切换为中文 1、在App.vue的文件中修改 <template><el-config-provider :locale"zhCn"><router-view></router-view></el-config-provider> </template><script lang"ts" setup>im…...

C#开发单实例应用程序并响应后续进程启动参数

C#默认的WinForm模板是不支持设置单实例的&#xff0c;也没有隔壁大哥VB.NET那样有个“生成单个实例应用程序”的勾选选项&#xff08;VB某些时候要比C#更方便&#xff09;&#xff0c;实现单实例可以有多种方法&#xff1a; 检测同名进程&#xff1a;Process.GetProcessesByNa…...

STM32智能机器人导航系统教程

目录 引言环境准备智能机器人导航系统基础代码实现&#xff1a;实现智能机器人导航系统 4.1 数据采集模块 4.2 数据处理与导航算法 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;机器人导航应用与优化问题解决方案与优化收尾与总结 1. 引言 智能机器…...

QML与QWidget混合开发:实现高效UI集成的实战指南

1. 为什么需要QML与QWidget混合开发 在Qt开发中&#xff0c;QML和QWidget是两种完全不同的UI构建方式。QML凭借其声明式语法和强大的动画效果&#xff0c;在现代UI开发中越来越受欢迎。但现实情况是&#xff0c;很多成熟的功能模块都是基于QWidget开发的&#xff0c;比如一些第…...

突破限制与全版本支持:MediaCreationTool.bat重新定义Windows安装介质制作

突破限制与全版本支持&#xff1a;MediaCreationTool.bat重新定义Windows安装介质制作 【免费下载链接】MediaCreationTool.bat Universal MCT wrapper script for all Windows 10/11 versions from 1507 to 21H2! 项目地址: https://gitcode.com/gh_mirrors/me/MediaCreatio…...

ENVI实战:利用传感器波谱响应函数实现光谱曲线精准重采样

1. 为什么需要光谱重采样&#xff1f; 在遥感数据分析中&#xff0c;我们经常会遇到一个头疼的问题&#xff1a;不同传感器采集的光谱数据分辨率不一致。比如实验室用光谱仪测量的叶片反射率可能有上千个波段&#xff0c;而Landsat-8卫星只能获取11个波段的数据。这就好比用高清…...

Legacy iOS Kit终极指南:解锁旧iOS设备的完整控制权

Legacy iOS Kit终极指南&#xff1a;解锁旧iOS设备的完整控制权 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to restore/downgrade, save SHSH blobs, jailbreak legacy iOS devices, and more 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit 在…...

告别手动刷课!智慧树网课助手让你的学习效率提升50%

告别手动刷课&#xff01;智慧树网课助手让你的学习效率提升50% 【免费下载链接】zhihuishu 智慧树刷课插件&#xff0c;自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 你是否厌倦了在智慧树平台上频繁点击"下一集"…...

找不到msvcr120.dll解决方法:2026年有效的一键修复与手动安装步骤

正玩着游戏或做着设计图&#xff0c;屏幕突然弹出“找不到msvcr120.dll”的提示&#xff0c;相信很多Windows用户都遇到过这种令人抓狂的时刻。这个错误意味着你的电脑缺少了某个软件或游戏运行所必需的“零件”。别担心&#xff0c;这个零件就是Microsoft Visual C 2013运行库…...

Apprise:一个库统治所有推送通知平台的终极解决方案

Apprise&#xff1a;一个库统治所有推送通知平台的终极解决方案 前言 在日常开发与运维工作中&#xff0c;我们经常需要将系统状态、告警信息或业务事件通过各种渠道推送给相关人员——可能是 Telegram、企业微信、钉钉、邮件&#xff0c;也可能是 Slack、Discord 或 PushBulle…...

OpenSpeedy高效构建与分发指南:从源码到部署的全流程实践

OpenSpeedy高效构建与分发指南&#xff1a;从源码到部署的全流程实践 【免费下载链接】OpenSpeedy &#x1f3ae; An open-source game speed modifier. 项目地址: https://gitcode.com/gh_mirrors/op/OpenSpeedy OpenSpeedy作为一款专注于提升GitHub资源访问速度的开源…...

Claude Code编程助手实践:辅助编写cv_resnet101模型调用代码

Claude Code编程助手实践&#xff1a;辅助编写cv_resnet101模型调用代码 不知道你有没有过这样的经历&#xff1a;项目急着要上线&#xff0c;需要调用一个像ResNet101这样的图像分类模型&#xff0c;但对着API文档&#xff0c;光是搞明白参数怎么传、返回结果怎么解析&#x…...

从Java全栈工程师视角看Web开发的实战与思考

从Java全栈工程师视角看Web开发的实战与思考 面试现场&#xff1a;一次真实的技术对话 面试官&#xff1a;你好&#xff0c;我是今天的面试官&#xff0c;很高兴见到你。请先简单介绍一下自己。 应聘者&#xff1a;你好&#xff0c;我叫李明&#xff0c;28岁&#xff0c;本科学…...