【DP解密多重背包问题】:优化策略与实现

文章目录

  • 什么是多重背包问题?
    • 多重背包问题的数学模型
  • 例题
    • 多重背包问题Ⅰ
    • 多重背包问题Ⅱ
  • 总结

在这里插入图片描述

什么是多重背包问题?

多重背包问题是一个经典的组合优化问题。与标准背包问题不同,在多重背包问题中,每种物品可以选择多个,而不是只选择一次。具体来说,给定一个背包的容量和若干种物品,每种物品有一个重量和价值,目标是最大化在背包中放入的物品总价值,同时不超过背包的容量。

在解决这个问题时,通常使用动态规划或贪心算法,具体取决于问题的约束条件。
在日常生活中,我们常常面临选择的困扰,如何在有限的资源下最大化收益?多重背包问题正是这种选择的数学模型。具体而言,给定一个背包的容量 C C C n n n 种物品,每种物品 i i i 具有重量 w w w 和价值 v v v,而且可以选择多个单位。我们的目标是最大化总价值,同时不超过背包的容量。

多重背包问题的数学模型

我们可以通过以下公式来表示多重背包问题:

max ⁡ ∑ i = 1 n v i ⋅ x i \max \sum_{i=1}^{n} v_i \cdot x_i maxi=1nvixi

其中, x i x_i xi 表示选择物品 i i i 的数量,满足以下约束条件:

∑ i = 1 n w i ⋅ x i ≤ C \sum_{i=1}^{n} w_i \cdot x_i \leq C i=1nwixiC

x i ∈ Z ≥ 0 x_i \in \mathbb{Z}_{\geq 0} xiZ0

接下来会展示几道例题。

例题

多重背包问题Ⅰ

问题:

在这里插入图片描述

输出格式和数据范围:

在这里插入图片描述

样例输出和输入:

在这里插入图片描述

算法原理:
相较于01背包问题来说,多重背包问题当中每个物品的个数不止是一个而是多个。相较于完全背包问题来说这些物品都不是无锡无限的。
举个例子:

物品标号1234
单个物品容量1234
物品个数3132
单个物品价值2445

以上面这个为例子,假设背包的容量是5,可以选择的物品个数是4,我们该如何选择呢,按照01背包问题的思想:我们可以先创建一个dp数组,dp[i]表示物品容量是i时的最大价值。
在 0-1 背包问题中,每个物品只能选择一次,因此状态转移方程是:

d p [ j ] = m a x ( d p [ j ] , d p [ j − v [ i ] ] + w [ i ] ) dp[j] = max(dp[j], dp[j - v[i]] + w[i]) dp[j]=max(dp[j],dp[jv[i]]+w[i])

其中, d p [ j ] dp[j] dp[j]表示容量为 j j j时的最大价值。

在多重背包问题中,每个物品有多个数量可以选择,因此状态转移方程变为:

d p [ j ] = m a x ( d p [ j ] , d p [ j − v [ i ] ] + w [ i ] , d p [ j − 2 v [ i ] ] + 2 w [ i ] , … , d p [ j − n v [ i ] ] + n w [ i ] ) dp[j] = max(dp[j], dp[j - v[i]] + w[i], dp[j - 2v[i]] + 2w[i], \dots, dp[j - nv[i]] + nw[i]) dp[j]=max(dp[j],dp[jv[i]]+w[i],dp[j2v[i]]+2w[i],,dp[jnv[i]]+nw[i])

这个公式的解释是,针对每个容量 j j j,我们考虑物品 i i i 的不同数量,找到一个最优的数量组合,使得价值最大化。

解释:

  1. 当选择 0 个物品 i i i 时,价值为 d p [ j ] dp[j] dp[j]
  2. 当选择 1 个物品 i i i 时,价值为 d p [ j − v [ i ] ] + w [ i ] dp[j - v[i]] + w[i] dp[jv[i]]+w[i]
  3. 当选择 2 个物品 i i i时,价值为 d p [ j − 2 v [ i ] ] + 2 w [ i ] dp[j - 2v[i]] + 2w[i] dp[j2v[i]]+2w[i]
  4. 依此类推,直到选择最多 n n n个物品 i i i

因此,针对每个容量 ( j ),我们计算每种数量下的最大值,并更新 d p [ j ] dp[j] dp[j]

所以我们需要一个循环来遍历每一种个数的情况:
在这里插入图片描述

代码展示:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main()
{int N,V;cin>>N>>V;vector<int> dp(V+1,0);for(int i=0;i<N;i++){int vi,wi,si;cin>>vi>>wi>>si;for(int j=V;j>=vi;j--){for(int k=1;k<=si&&j>=k*vi;k++){dp[j]=max(dp[j],dp[j-k*vi]+k*wi);}}}cout<<dp[V]<<endl;return 0;
}

多重背包问题Ⅱ

问题:

在这里插入图片描述

数据范围:

在这里插入图片描述

输入样例和输出样例:

在这里插入图片描述

可以看见这道题的题目要求和上道题一模一样,但是数据范围发生了变化,我们先看看上道题的数据范围是100,100,100。套了三层循环顶多也就100万,对于C++来说100万是可以接受的,但是这道题的数据范围是1000,2000,2000,算出来是 4 ∗ 1 0 9 4*10^9 4109,用刚才那种算法是会超时的。

算法优化:
假如某个物品有7个,我们是不是可以将这7个物品分为若干份,最容易想到的:
七个物品我们可以分为7份,然后每个物品的物品数量也可以相应的划分,是不是可以转换为一个01背包问题,但是这里我们划分的份数是不是太多了,我们可以来简化一下,我是否可以将一个物品的数量划分为2的幂次方个之和,就拿上面的例子为例,7个物品,我们可以划分为:1+2+4,这里很巧合的是刚刚好划分完了,但是如果我们有8个物品呢?是不是最后还剩下一一个,这个不能划分为2的幂次方的我们单独讨论即可,我们将每个物品分好组之后然后进行一次01背包问题即可。
在处理多重背包问题时,我们可以使用二进制拆分的方法来简化问题。

原因与解释:

  1. 二进制拆分

    • 每个物品的数量可以被表示为一系列 2 的幂次方之和。这是因为任何正整数都可以通过二进制表示来拆分成若干个 1、2、4、8 等的组合。例如,数字 7 可以拆分为 (1 + 2 + 4)。
    • 对于 8 这个例子,你可以将其拆分为 (8) 或者 (4 + 4)(视情况而定)。这个方法将减少需要考虑的物品种类,使得后续的背包问题更容易处理。
  2. 减少物品种类

    • 通过将物品的数量拆分为 2 的幂次方,我们实际上减少了在解决背包问题时所需考虑的物品数量。例如,7 个物品可以看作 1 个物品(1 个)、1 个物品(2 个)和 1 个物品(4 个),而不是直接处理 7 个物品。
    • 这使得问题转变为多个 0-1 背包问题,每个物品的“虚拟”数量在其对应的 0-1 背包问题中被考虑。
  3. 独立处理剩余物品

    • 如果在拆分后有剩余的物品(例如在处理 8 个物品时多出 1 个),可以单独将这一部分作为一个新的物品进行处理。这不会影响已经拆分的部分,因为已经处理的组合都是由 2 的幂构成的。

总结:
通过将物品数量拆分为 2 的幂次方之和,你可以有效地将多重背包问题转换为多个 0-1 背包问题,简化问题的复杂性,并且只需关注相对较少的物品组合。这个策略的有效性源于数学上对整数的分解性质,确保了每个可能的选择都能够被覆盖。

代码展示:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;//大数据范围用二进制分解优化const int V=2001;
int n,m;struct Good
{//容量int v;//价值int w;
};int main()
{vector<Good> good;vector<int> dp(V,0);cin>>n>>m;for(int i=0;i<n;i++){int vi,wi,si;cin>>vi>>wi>>si;for(int k=1;k<=si;k*=2){si-=k;good.push_back({k*vi,k*wi});}//有剩的,但是不能组成2的幂次方if(si>0)good.push_back({si*vi,si*wi});}//重新做一次01背包for(auto e:good){for(int j=m;j>=e.v;j--){dp[j]=max(dp[j],dp[j-e.v]+e.w);}}cout<<dp[m]<<endl;return 0;
}

总结

在本文中,我们深入探讨了多重背包问题的动态规划解法及其优化策略。通过将物品的数量拆分为 2 的幂次方之和,我们成功地将复杂的多重背包问题转换为多个简单的 0-1 背包问题,从而降低了计算复杂度,提高了算法的效率。此外,结合具体实例和详细的代码实现,使得这一理论变得更为实用。

多重背包问题不仅在计算机科学中有着重要的应用,还在现实生活中为资源分配、库存管理等问题提供了有效的解决方案。掌握这一算法思路,可以为解决更复杂的组合优化问题奠定基础。

希望通过本篇文章,读者能够更好地理解多重背包问题,并在实际编程中灵活运用这些优化策略。

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

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

相关文章

蓝桥杯15届C/C++B组省赛题目

问题描述 小蓝组织了一场算法交流会议&#xff0c;总共有 5050 人参加了本次会议。在会议上&#xff0c;大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手 (且仅有一次)。但有 77 个人&#xff0c;这 77 人彼此之间没有进行握手 (但这 77 人与…

1.分页查询(后端)—— Vue3 + SpringCloud 5 + MyBatisPlus + MySQL 项目系列(基于 Zulu 11)

本手册是基于 Vue3 SpringCloud5 MyBatisPlus MySQL 的项目结构和代码实现&#xff0c;旨在作为一个教学案例进行讲解。为了使案例更具普适性&#xff0c;文档中的公司名称、实体类、表名以及字段名称等敏感信息均已脱敏。 项目结构概述 项目采用标准的分层架构&#xff0…

linux命令之firewall-cmd用法

firewall-cmd Linux上新用的防火墙软件&#xff0c;跟iptables差不多的工具 补充说明 firewall-cmd 是 firewalld的字符界面管理工具&#xff0c;firewalld是centos7的一大特性&#xff0c;最大的好处有两个&#xff1a;支持动态更新&#xff0c;不用重启服务&#xff1b;第…

Spring Mybatis 动态语句 总结

1.简介 Mybatis 提供动态语句的功能来增强多条件变动的查询语句。 2.代码 if和where搭配使用&#xff1a; <select id"query" resultType"a">select * from t_a<where><!-- where内没有条件满足&#xff0c;不转成where&#xff0c;有…

langchain v0.3更新了什么?

版本改动 这是具体改动的链接 官方blog首先说明了&#xff1a; 所有软件包已在内部从 Pydantic 1 升级到 Pydantic 2。 所有软件包都完全支持在用户代码中使用 Pydantic 2&#xff0c;而无需使用 langchain_core.pydantic_v1 或 pydantic.v1 等桥接程序。 由于 Pydantic 1 已…

Python爬虫bs4基本使用

一、bs4 1、bs4获得标记的子集或父集或兄弟节点 &#xff08;1&#xff09;子集&#xff1a; 通过contents和children可以获得子集&#xff0c;前者获得的是字符串列表&#xff0c;后者获得的是一个列表迭代器对象&#xff0c;需要遍历获得内容 比如我们有以下代码和数据&a…

Android LiveData 数据倒灌

相关类型的文章很多&#xff0c;这里只做个人总结和其余的方法推荐 1.什么是数据倒灌&#xff1f; 所谓的“数据倒灌”&#xff1a;其实是类似粘性广播那样&#xff0c;当新的观察者开始注册观察时&#xff0c;会把上次发的最后一次的历史数据传递给当前注册的观察者。 一方…

【HTTP】请求“报头”(Host、Content-Length/Content-Type、User-Agent(简称 UA))

Host 表示服务器主机的地址和端口号 URL 里面不是已经有 Host 了吗&#xff0c;为什么还要写一次&#xff1f; 这里的 Host 和 URL 中的 IP 地址、端口什么的&#xff0c;绝大部分情况下是一样的&#xff0c;少数情况下可能不同当前我们经过某个代理进行转发。过程中&#xf…

2024年项目经理不能错过的开源项目管理系统大盘点:全面指南

在2024年&#xff0c;随着项目管理领域的不断发展&#xff0c;开源项目管理系统成为了项目经理们提升工作效率的利器。本文将全面盘点几款备受推荐的开源项目管理系统&#xff0c;帮助项目经理们找到最佳选择&#xff0c;不容错过。 在项目管理日益复杂的今天&#xff0c;开源项…

腾讯云点播及声音上传

文章目录 1、开通腾讯云点播2、获取腾讯云API密钥3、完成声音上传3.1、引入依赖3.2、参考&#xff1a;接入点地域3.3、参考&#xff1a;任务流设置3.4、首先修改配置&#xff1a;3.4.1、 3.5、TrackInfoApiController --》 uploadTrack()3.6、VodServiceImpl --》 uploadTrack(…

SOLIDWORKS Flow Simulation对几何模型都有哪些要求?

SOLIDWORKS Flow Simulation 是一款集设计与仿真于一体的流体仿真软件&#xff08;EFD&#xff0c;CFD&#xff09;&#xff0c;以其操作简便、建模快捷和快速收敛等优点&#xff0c;深受广大初学者的喜爱。 在模型建立方面&#xff0c;Flow Simulation 能够直接利用 SOLIDWOR…

论文解读《Object-Centric Learning with Slot Attention》

系列文章目录 文章目录 系列文章目录论文细节理解 1. 研究背景2. 论文贡献3. 方法框架3.1 Slot Attention模块3.2 无监督对象发现架构 4. 研究思路5. 实验6. 限制 论文细节理解 supervised property prediction tasks是什么&#xff1f; Supervised property prediction tasks…

项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持windows、linux、国产麒麟系统)

若该文为原创文章&#xff0c;转载请注明出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/142454993 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、Op…

数据科学 - 字符文本处理

1. 字符串的基本操作 1.1 结构操作 1.1.1 拼接 • 字符串之间拼接 字符串之间的拼接使用进行字符串的拼接 a World b Hello print(b a) • 列表中的字符串拼接 将以分隔符‘,’为例子 str [apple,banana] print(,.join(str)); • 字符串中选择 通过索引进行切片操…

【网络安全】-访问控制-burp(1~6)

文章目录 前言   1.Lab: Unprotected admin functionality  2.Lab: Unprotected admin functionality with unpredictable URL   3.Lab: User role controlled by request parameter   4.Lab:User role can be modified in user profile  5.Lab: User ID controlled by…

Windows 10 系统安装 FFmpeg 查看、转换、编辑音频文件

1、FFmpeg官网&#xff1a;FFmpeg 点击下载 可以选择下载full版本 下载之后解压到指定目录&#xff0c;在系统环境变量 Path 里面新增环境变量 打开CMD终端运行 ffmpeg -version 查看是否安装成功。 2、基本命令 查看音频基本信息 ffprobe 1.mp3 ##输出 [mp3 000002ab334405…

LLM - 使用 XTuner 指令微调 多模态大语言模型(InternVL2) 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142528967 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 XTuner…

Spark-RDD持久化

一、Spark的三种持久化机制 1、cache 它是persist的一种简化方式&#xff0c;作用是将RDD缓存到内存中&#xff0c;以便后续快速访问&#xff0c;提高计算效率。cache操作是懒执行的&#xff0c;即执行action算子时才会触发。 2、persist 它提供了不同的存储级别&#xff0…

关于神经网络的一个介绍

这篇文章中&#xff0c;我将简单介绍下与神经网络有关的东西&#xff0c;包括它的基本模型&#xff0c;典型的算法以及与深度学习的联系等内容。 一、神经元 神经网络是由许多个神经元组成的&#xff0c;在生物的神经网络中&#xff0c;就是神经元间相互连接&#xff0c;传递…

高校竞赛管理系统的设计与实现

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统高校竞赛管理系统信息管理难度大&#xff0c;容错率低&am…