DP:背包问题----0/1背包问题

news2024/12/23 20:23:14

文章目录

  • 💗背包问题
    • 💛背包问题的变体
    • 🧡0/1 背包问题的数学定义
    • 💚解决背包问题的方法
    • 💙例子
  • 💗解决背包问题的一般步骤?
  • 💗例题
  • 💗总结

在这里插入图片描述

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

💗背包问题

背包问题(Knapsack Problem)是一类经典的组合优化问题,在计算机科学和数学中有广泛应用。其基本问题是:

  • 输入:给定一个容量为 W W W 的背包和 n n n 个物品,每个物品 i i i 有一个重量 w i w_i wi 和一个价值 v i v_i vi
  • 目标:选择若干个物品放入背包,使得总重量不超过背包的容量 W W W,并且总价值最大化。

💛背包问题的变体

  1. 0/1 背包问题:每个物品只能选择一次,即要么选中(1)要么不选(0)。
  2. 分数背包问题:每个物品可以分割,即可以选择物品的一部分。
  3. 多重背包问题:每个物品有多个副本,可以选择多个相同的物品。
  4. 多维背包问题:背包有多个限制条件,例如容量和体积等。

🧡0/1 背包问题的数学定义

目标函数:
maximize ∑ i = 1 n c i ⋅ x i \text{maximize} \sum_{i=1}^{n} c_i \cdot x_i maximizei=1ncixi
其中, n n n 表示物品的数量, c i c_i ci 表示物品 i i i 的价值。

约束条件:
∑ i = 1 n w i ⋅ x i ≤ C \sum_{i=1}^{n} w_i \cdot x_i \leq C i=1nwixiC
其中, w i w_i wi 表示物品 i i i 的重量, C C C 表示背包的容量。

其它约束条件:
x i ∈ { 0 , 1 } x_i \in \{0,1\} xi{0,1}
i = 1 , 2 , 3 , … , n i = 1,2,3,\ldots,n i=1,2,3,,n
其中, x i x_i xi 表示物品 i i i 是否被选中。

💚解决背包问题的方法

解决背包问题的方法有很多,包括动态规划、分支定界法、贪心算法(适用于分数背包问题)以及各种近似算法和启发式算法等。

💙例子

假设有一个背包容量为 50 的背包,有以下物品:

物品重量价值
11060
220100
330120

目标是选择物品使得总重量不超过 50 且总价值最大化。在这个例子中,最佳选择是选取物品 2 和物品 3,总重量为 50,总价值为 220。

💗解决背包问题的一般步骤?

背包问题是一个经典的优化问题,可以通过动态规划算法来解决。下面是解决背包问题的一般步骤:

  1. 确定问题的约束条件:背包的容量限制和物品的重量和价值。

  2. 定义状态:将问题拆解为多个子问题,定义状态为背包的容量和可选择的物品。

  3. 定义状态转移方程:根据子问题的定义,确定状态之间的关系。例如,对于背包问题,可以定义状态转移方程为f(i,j),表示在前i个物品中选择,背包容量为j时,可以获得的最大价值。则可以得到状态转移方程:f(i,j) = max(f(i-1,j), f(i-1,j-w[i])+v[i]),其中w[i]和v[i]分别表示第i个物品的重量和价值。

  4. 确定初始条件:确定边界条件,即背包容量为0时,价值为0。

  5. 通过动态规划算法计算最优解:根据状态转移方程和初始条件,利用循环或递归的方式计算最优解。

  6. 回溯最优解:根据计算得到的最优解,可以通过回溯的方式确定选择了哪些物品放入背包中,从而得到最终的解。

需要注意的是,背包问题的解决方法还包括贪心算法、分支界限算法等。具体选择哪种方法取决于问题的约束条件和需要优化的目标。

💗例题

题目链接
题目:

在这里插入图片描述

样例输出和输入:

在这里插入图片描述

这道题并不是leetcode的那种接口的模式,而是ACM模式,我们需要进行完整的输入和输出,我们先分析第一个样例:

0123
容量241
价值1054

第一个问题是给定一个背包容量,求出当背包的容量不用装满时的最大价值,意思就是我们选出的物品的总的容量可以小于背包的容量,也可以等于背包的容量,这时,我们可以第一个物品和三个物品的价值是最大的。
总价值为14,
第二个问题是我们必须将 背包容量给塞满,求塞满的状态的物品的最大价值,这种情况下有可能是没有结果的,因为无法选出能将背包塞满的组合 ,所以这时候就输出零。但是这个例子是可以输出结果的,塞满的情况应该是第二个物品和第三个物品,总价值是9,所以最后输出14和9。

算法原理:
状态表示:dp[i][j]-----表示选到第i个位置时的所有选法中的不超过总容积j的最大价值。
状态转移方程:在这里插入图片描述
这是不把背包填满的情况下的状态转移方程,还有一个问题就是需要将背包填满。
在这里插入图片描述
所以这里如果要用到前一个状态的话,应该判断一下前一个状态是否是-1,如果前一个状态是-1的话,就表示这种情况根本不存在 ,所以不能选择这种状态在这里插入图片描述

初始化:第一个问题的初始化只需要将dp表初始化为0,第二个问题的初始化上面已经讨论过了。
填表顺序:也是按照从左上角到右下角,依次填表。
返回值:返回dp[n][V]
代码展示:

#include <cstring>
#include <iostream>
#include<string>
using namespace std;

//数据范围
const int N = 1010;
//n个数据,V为背包的总容量,v表示单个物品的所占容积,w表示单个物品所含的价值
int n, V, v[N], w[N];
//i表示第i个位置,j表示总的容积
int dp[N][N];

int main()
{
    //输入总数据,和总容积
    cin >> n >> V;
    for (int i = 1;i <= n;i++)
    {
        cin >> v[i] >> w[i];
    }
    //解决第一问
    for (int i = 1;i <= n;i++)
    {
        //j表示容量
        for (int j = 1;j <= V;j++)
        {
            //不选的情况
            dp[i][j] = dp[i - 1][j];
            //如果能选,则和之前不选的情况求一个max
            if (j >= v[i])dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i]] + w[i]);
        }
    }
    //输出最后一个dp状态
    cout << dp[n][V] << endl;
    //重置dp表,将表中数据重置为0
    memset(dp, 0, sizeof dp);
    //单独初始化第一排的后面的位置,因为如果没有任何物品根本不可能有价值,所以初始化为-1
    for (int i = 1;i <= V;i++)
    {
        //初始化不存在dp的位置
        dp[0][i] = -1;
    }
    for (int i = 1;i <= n;i++)
    {
        //j表示容量
        for (int j = 1;j <= V;j++)
        {
            //可以不选
            dp[i][j] = dp[i - 1][j];
            //如果要选择当前位置的话需要考虑前一个状态是否是-1,选不到的情况 
            if (j >= v[i] && dp[i - 1][j - v[i]] != -1)
                dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i]] + w[i]);
        }
    }
    //如果不存在选满的情况,直接返回0,否则返回dp[n][V]位置的值
    cout << (dp[n][V] == -1 ? 0 : dp[n][V]) << endl;
    return 0;
}

代码优化:
可以利用滚动数组进行优化:

#include <cstring>
#include <iostream>
#include<string>
using namespace std;

//数据范围
const int N = 1010;
//n个数据,V为背包的总容量,v表示单个物品的所占容积,w表示单个物品所含的价值
int n, V, v[N], w[N];
//i表示第i个位置,j表示总的容积
int dp[N];

int main()
{
    //输入总数据,和总容积
    cin >> n >> V;
    for (int i = 1;i <= n;i++)
        cin >> v[i] >> w[i];
    //解决第一问
    for (int i = 1;i <= n;i++)
        //j表示容量
        for (int j = V;j >= v[i];j--)//修改遍历顺序
            //如果能选,则和之前不选的情况求一个max
            dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
    //输出最后一个dp状态
    cout << dp[V] << endl;
    //重置dp表,将表中数据重置为0
    memset(dp, 0, sizeof dp);
    //单独初始化第一排的后面的位置,因为如果没有任何物品根本不可能有价值,所以初始化为-1
    for (int i = 1;i <= V;i++)
        //初始化不存在dp的位置
        dp[i] = -1;
    for (int i = 1;i <= n;i++)
        //j表示容量
        for (int j = V;j >= v[i];j--)//修改遍历顺序
            //如果能选,则和之前不选的情况求一个max
            if(dp[j-v[i]]!=-1)
            dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
    //如果不存在选满的情况,直接返回0,否则返回dp[n][V]位置的值
    cout << (dp[V] == -1 ? 0 : dp[V]) << endl;
    return 0;
}

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

💗总结

通过对0/1背包问题的分析和动态规划解法的详细讲解,我们可以看到这种经典问题在算法设计中的重要性。0/1背包问题不仅是许多实际应用的基础,也是理解和掌握动态规划思想的一个重要实例。

在解决0/1背包问题时,关键在于构建状态转移方程并合理使用空间和时间资源。通过递归和迭代的方法,我们能更好地理解背包问题的解法,优化算法效率,并提升解决复杂问题的能力。

希望这篇博客能帮助你理解0/1背包问题的基本原理和解法,同时激发你对动态规划和算法设计的进一步兴趣和探索。未来的学习中,不妨尝试更多的变种背包问题和动态规划问题,以不断提升自己的算法技能和编程水平。

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

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

相关文章

力扣Hot100-19删除链表的倒数第n个节点(双指针)

给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[]示例 3&#xff1a;…

UCOS-III 任务调度与就绪列表管理

01. 就绪优先级位图 在实时操作系统中&#xff0c;任务调度的效率至关重要。UCOS-III通过就绪优先级位图来快速查找最高优先级的就绪任务&#xff0c;从而实现高效调度。就绪优先级位图是一个按位表示的结构&#xff0c;每个位代表一个优先级&#xff0c;当某个优先级上有任务就…

本地Windows电脑 连接 Windows 服务器

Windows电脑 连接 Windows 服务器 方式1&#xff1a;直接搜索 在电脑的搜索栏&#xff0c;输入“远程桌面连接” 可以选择点击 “打开” 或者直接按 回车键 “Enter”&#xff0c;打开 远程桌面连接 方式2&#xff1a;运行框打开服务器连接 同时按&#xff1a;Windows徽标键…

分布式数据库HBase:从零开始了解列式存储

在接触过大量的传统关系型数据库后你可能会有一些新的问题: 无法整理成表格的海量数据该如何储存? 在数据非常稀疏的情况下也必须将数据存储成关系型数据库吗? 除了关系型数据库我们是否还有别的选择以应对Web2.0时代的海量数据? 如果你也曾经想到过这些问题, 那么HBase将是…

CTF之unseping

拿到题目看不懂&#xff1f;这是难度1&#xff1f;含泪去看大佬的wp&#xff0c;写下我的自传&#xff01; <?php highlig…

常微分方程算法之编程示例十-两点狄利克雷边值问题(理查德森外推法)

目录 一、研究问题 二、C++代码 三、计算结果 一、研究问题 本节我们采用理查德森法对示例八中的两点狄利克雷边值问题进行外推求解,相应的原理及推导思路请参考: 常微分方程算法之高精度算法(Richardson法+紧差分法)_richardson外推法-CSDN博客https://blog.csdn.net/…

【SVN的使用-源代码管理工具-SVN介绍-服务器的搭建 Objective-C语言】

一、首先,我们来介绍一下源代码管理工具 1.源代码管理工具的起源 为什么会出现源代码管理工具,是为了解决源代码开发的过程中出现的很多问题: 1)无法后悔:把项目关了,无法Command + Z后悔, 2)版本备份:非空间、费时间、写的名称最后自己都忘了干什么的了, 3)版本…

【服装识别系统】图像识别+Python+人工智能+深度学习+算法模型+TensorFlow

一、介绍 服装识别系统&#xff0c;本系统作为图像识别方面的一个典型应用&#xff0c;使用Python作为主要编程语言&#xff0c;并通过TensorFlow搭建ResNet50卷积神经算法网络模型&#xff0c;通过对18种不同的服装&#xff08;‘黑色连衣裙’, ‘黑色衬衫’, ‘黑色鞋子’, …

Linux多进程和多线程(五)进程间通信-消息队列

多进程(五) 进程间通信 消息队列 ftok()函数创建消息队列 创建消息队列示例 msgctl 函数示例:在上⼀个示例的基础上&#xff0c;加上删除队列的代码 发送消息 示例: 接收消息示例 多进程(五) 进程间通信 消息队列 消息队列是一种进程间通信机制&#xff0c;它允许两个或多个…

终身免费的Navicat数据库,不需要破解,官方支持

终身免费的Navicat数据库&#xff0c;不需要破解&#xff0c;官方支持 卸载了Navicat&#xff0c;很不爽上干货&#xff0c;Navicat免费版下载地址 卸载了Navicat&#xff0c;很不爽 公司不让用那些破解的数据库软件&#xff0c;之前一直使用Navicat。换了几款其他的数据库试了…

大数据开发如何快速进阶

目录 1. 个人经验与心得分享1.1 试错的价值与机会把握1.2 投入产出比的考量1.3 刻意练习与技能提升1.4 目标设定与职业规划1.5 自我驱动与成长1.6 第一性原理的应用 2. 大数据开发领域的挑战与机遇2.1 技术革新的挑战2.2 数据治理的难题2.3 人才短缺的问题2.4 投入产出比的考量…

电子部件烧录流程(仅供参考)

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 部件烧录流程的详细步骤 1. 准备工作 2. 连接硬件 3. 配置烧录软件 4. 校验和设置 5. 开始烧录 6. 验证和测试 7. 断开…

Docker实现Redis主从,以及哨兵机制

Docker实现Redis主从,以及哨兵机制 目录 Docker实现Redis主从,以及哨兵机制准备Redis镜像创建Redis主节点配置文件启动Redis从节点确认主从连接哨兵主要功能配置哨兵文件创建Redis哨兵的Docker容器 要通过Docker实现Redis的主从&#xff08;master-slave&#xff09;复制&#…

亚太万人eVTOL展!2024深圳eVTOL将于9月登陆鹏城

2024年以来&#xff0c;北京、上海等十多个省市&#xff0c;先后发布了鼓励低空经济发展的行动方案&#xff0c;其中&#xff0c;eVTOL&#xff08;电动垂直起降航空器&#xff09;成为低空经济最火热的细分赛道。2023年&#xff0c;中国eVTOL产业规模达9.8亿元&#xff0c;同比…

Cloud Kernel SIG 双月动态:ANCK 发布 4.19 6.6 新版本,存储、内存、调度等新特性支持

Cloud Kernel SIG&#xff08;Special Interest Group&#xff09;&#xff1a;支撑龙蜥内核版本的研发、发布和服务&#xff0c;提供生产可用的高性价比内核产品。 本月度动态综合汇总了 5 月和 4 月双月项目动态&#xff1a; 01 SIG 整体进展 5 月 1. ANCK-6.6 release 6…

基于RAG(检索增强生成)实现一套企业智能客服系统

大型语言模型&#xff08;LLM&#xff09;相较于传统的语言模型具有更强大的能力&#xff0c;然而在某些情况下&#xff0c;它们仍可能无法提供准确的答案。为了解决大型语言模型在生成文本时面临的一系列挑战&#xff0c;提高模型的性能和输出质量&#xff0c;研究人员提出了一…

软件测试面试必杀篇:【2024软件测试面试八股文宝典】

800道软件测试面试真题&#xff0c;高清打印版打包带走&#xff0c;横扫软件测试面试高频问题&#xff0c;涵盖测试理论、Linux、MySQL、Web测试、接口测试、App测试、Python、Selenium、性能测试、LordRunner、计算机网络、数据结构与算法、逻辑思维、人力资源等模块面试题&am…

ssm三农产品助推网站-计算机毕业设计源码91990

目录 摘要 1 绪论 1.1选题背景与意义 1.2国内外研究现状 1.3论文结构与章节安排 2网站分析 2.1 可行性分析 2.2 网站流程分析 2.2.1 数据流程 2.2.2 业务流程 2.3 网站功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 网站用例分析 2.5本章小结 3 网站总体设…

怎么在线打开AI文件?推荐使用这款免费白板软件!

在我们的日常生活和工作中&#xff0c;AI文件的使用频率越来越高。但是&#xff0c;对于许多非设计从业者来说&#xff0c;如何打开AI文件仍然是一个经常遇到的问题。 别担心&#xff0c;免费的在线白板软件就是你的解决方案。这种工具不仅可以轻松打开AI文件&#xff0c;还可…

AI 与数据的智能融合丨大模型时代下的存储系统

WOT 全球技术创新大会2024北京站于 6 月 22 日圆满落幕。本届大会以“智启新纪&#xff0c;慧创万物”为主题&#xff0c;邀请到 60 位不同行业的专家&#xff0c;聚焦 AIGC、领导力、研发效能、架构演进、大数据等热门技术话题进行分享。 近年来&#xff0c;数据和人工智能已…