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

news2024/9/27 18:42:56

文章目录

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

在这里插入图片描述

什么是多重背包问题?

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

在解决这个问题时,通常使用动态规划或贪心算法,具体取决于问题的约束条件。
在日常生活中,我们常常面临选择的困扰,如何在有限的资源下最大化收益?多重背包问题正是这种选择的数学模型。具体而言,给定一个背包的容量 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.coloradmin.cn/o/2170698.html

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

相关文章

数据链路层之以太网

目录 ​前言 什么是以太网&#xff1f; 以太网帧格式 6位源地址和目的地址 什么是MAC地址&#xff1f; MAC地址和IP地址的区别 2位类型 ARP协议 ARP协议的作用 ARP协议的工作流程 数据长度 MTU对IP协议的影响 CRC校验和 前言 在前面&#xff0c;我们已经讲了在TC…

安卓好软-----手机屏幕自动点击工具 无需root权限

工具可以设置后自动点击屏幕。可以用于一些操作。例如自动刷视频等等哦 工具介绍 一款可以帮你实现自动操作的软件。软件中你可以根据实际需要设置点击位置&#xff0c;可以是屏幕上的特定位置&#xff0c;也可以是按钮或控件。功能非常强大&#xff0c;但是操作非常简单&…

7个不为人知的实用软件推荐

今天再给大家分享7款不常被提及但又很好用的小众宝藏软件&#xff0c;强大实用&#xff0c;值得被更多的人看见&#xff01; 1.向日葵——电脑远程控制 下载链接&#xff1a;https://sunlogin.oray.com/ 对于很多电脑小白来说&#xff0c;其实很多软件安装、电脑调试之类的操…

Leetcode面试经典150题-383.赎金信

给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&#xff1a; 输入&#…

联宇集团:如何利用CRM实现客户管理精细化与业务流程高效协同

在全球化的浪潮中&#xff0c;跨境电商正成为国际贸易的新引擎。作为领先的跨境电商物流综合服务商&#xff0c;广东联宇物流有限公司(以下称“联宇集团”)以其卓越的物流服务和前瞻的数字化战略&#xff0c;在全球市场中脱颖而出。本文将基于联宇集团搭建CRM系统的实际案例&am…

链表以及字符串数据求和及乘积问题

目录 ​编辑 <->本篇简介&#xff1a; <二>题目解析解答&#xff1a; 21大数乘法问题&#xff1a; ①题目&#xff1a; ②思路汇总&#xff1a; ③解答代码&#xff1a; 22 大数加法问题&#xff1a; ①题目&#xff1a; ②思路汇总&#xff1a; ③解答…

【数据结构中的哈希】

泛黄的春联还残留在墙上.......................................................................................................... 文章目录 前言 一、【哈希结构的介绍】 1.1【哈希结构的概念】 1.2【哈希冲突】 1.3【哈希函数的设计】 1.4【应对哈希冲突的办法】 一、…

PostgreSQL 一张表多个字段关联另一张表

event_catalog 表 event 表 sql SELECT event.event_uuid, event.event_case_id, event.event_status, event.event_catalog_1, event.event_catalog_2, event.event_catalog_3, event.event_title, event.event_content, event.event_source, event.event_purpose, event.eve…

JZ2440开发板——使用S3C2440操作Nand Flash

以下内容源于韦东山课程的学习与整理&#xff0c;如有侵权请告知删除。 本篇文章涉及以下文档资料&#xff1a;S3C2440数据手册、Nand Flash数据手册&#xff08;有三份&#xff0c;看K9F2G08U0C即可&#xff09;、JZ2440开发板原理图。 一、JZ2440上的Nand Flash JZ2440开发…

部署wordpress项目

一、先部署mariadb 二、在远程登录工具上进行登录测试&#xff0c;端口号为30117&#xff0c;用户为 root&#xff0c;密码为123 三、使用测试工具&#xff1a; [rootk8s-master aaa]# kubectl exec -it pods/cluster-test0-58689d5d5d-7c49r -- bash 四、部署wordpress [root…

楼上还是楼下的暖气,谁家更好蹭?

前几天收到个私信&#xff0c;想了解楼上楼下哪一户开暖气对中间影响大。我看到后就想&#xff0c;妙啊&#xff0c;这样就不需要开暖气&#xff0c;让邻居家的热气传过来&#xff0c;得省多少取暖费&#xff1f;不过站在热力学的角度&#xff0c;我们今天就来研究一下这个问题…

Xcode报错:The request was denied by service delegate (SBMainWorkspace)

Xcode报错&#xff1a;The request was denied by service delegate (SBMainWorkspace) 造成的原因: &#xff08;1&#xff09;新的M2芯片的Mac电脑 (2) 此电脑首次安装启动Xcode的应用程序 (3&#xff09;此电脑未安装Rosetta 解决方法: &#xff08;1&#xff09;打开终端…

电商IM客服系统的主要功能 网站即时通讯软件源码or SaaS

电商IM客服系统在现代电商平台中扮演着至关重要的角色&#xff0c;提供了高效的客户服务解决方案。系统的多功能特性使其能够实时响应客户需求&#xff0c;解决问题并增加转化率。以下是电商IM客服系统的六大功能 1、实时在线聊天&#xff1a;支持顾客与客服实时沟通&#xff0…

php thinkphp 小程序发送订阅模板消息通知

小程序需要在我的模板中先选用模板 小程序需要先订阅模板 wx.requestSubscribeMessage({tmplIds: ["XII_0By8D9WabnUjVPB_8S1itsm2d4_xxx"],success:

C++:string类写时拷贝|引用计数

✨ Blog’s 主页: 白乐天_ξ( ✿&#xff1e;◡❛) &#x1f308; 个人Motto&#xff1a;他强任他强&#xff0c;清风拂山冈&#xff01; &#x1f4ab; 欢迎来到我的学习笔记&#xff01; 写时拷贝&#xff08;了解&#xff09; 参考博客&#xff1a;C写时拷贝的不同方案&…

前台项目启动/打包报错 Error: error:0308010C:digital envelope routines::unsupported

在package.json中修改启动/打包语句 如图&#xff0c;我这里是打包时候报错&#xff0c;就在build里前面加上 set NODE_OPTIONS--openssl-legacy-provider && 再次打包&#xff0c;成功。

了解HTTPS

目录 1.HTTP认识 2.HTTP请求 3.HTTP响应 4.URL 5.HTTP方法 面试题&#xff1a;POST 和 GET区别&#xff1f; 网上关于 GET 与 POST的差别 有待商议 关于请求报头 和 响应报头 6..Host &#xff1a; 7..USer-Agent&#xff08;简称UA&#xff09; 8.状态码 9.HTTPS 是…

使用Charles抓包Android App数据

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 抓包环境准备 1. 下载安装charles charles下载地址&#xff1a;https://www.charlesproxy.com/latest-release/download.do 2. SSL代理设置 3. http代理和…

七段 LED 显示器(7段数码管)

7 段 LED 显示器, 通常简称为 LED 数码管 或 数码管. 通过 菜单--绘制--数字芯片--添加 7 段 LED 显示器 可以引入它. 普通模式 它内部其实就是七盏长条状的 LED 灯, 有的横着放, 有的竖着放. 七个灯用 a b c d e f g 分别表示. 灯的位置从上到下, 从里到外顺时针下来, 如上图…

240925-GAN生成对抗网络

GAN生成对抗网络 GAN&#xff0c;顾名思义&#xff0c;gan……咳咳&#xff0c;就是干仗嘛&#xff08;听子豪兄的课讲说这个名字还真的源于中文这个字&#xff09;&#xff0c;对应的就有两方&#xff0c;放在这里就是有两个网络互相对抗互相学习。类比武林高手切磋&#xff…