[Algorithm][动态规划][01背包问题][模板 背包][分割等和子集]详细讲解 +何为背包问题?

目录

  • 0.何为背包问题?
  • 1.模板 背包
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.分割等和子集
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


0.何为背包问题?

  • 背包问题:有限制条件下的"组合问题"

  • 你有一个背包,地上有一堆物品,挑选一些物品放入背包中

    • 问:最大能挑选出来的价值是多少?
  • 限制因素

    • 物品的属性:价值等
    • 背包的属性:容量大小等
    • 背包是要求必装满还是不必装满?
      请添加图片描述
  • 当研究一个问题,出现选或者不选的情况,思路就可以往01背包上靠

  • 注意:背包问题是必须要掌握的算法问题


1.模板 背包

1.题目链接

  • [模板] 背包

2.算法原理详解

  • 注意:01背包问题是所有背包问题的基础,此处的分析思路,可以用到很多题里面
  • 思路
    • 确定状态表示 -> dp[i][j]的含义

      • dp[i]:从前i个物品中选,所有选法中,能挑选出来的最大价值 ×
        • 无法得知背包容量
      • 不要求恰好装满
        • dp[i][j]:从前i个物品中挑选,总体积不超过j,所有选法中,能挑选出来的最大价值
      • 要求恰好装满
        • dp[i][j]:从前i个物品中挑选,总体积恰好等于j,所有选法中,能挑选出来的最大价值
    • 推导状态转移方程:根据最后一个位置的情况,分情况讨论

      • 不要求恰好装满:j - v[i] >= 0是为了确保背包此时容量足够塞下当前物品
        请添加图片描述

      • 要求恰好装满dp[i][j] == -1表示没有这种情况,即此时总体积凑不到j
        请添加图片描述

    • 初始化:

      • 不要求恰好装满vector<vector<int>> dp(n + 1, vector<int>(V + 1))
      • 要求恰好装满:第一行除第一个位置,其余都为-1
    • 确定填表顺序:从上往下

    • 确定返回值:

      • 不要求恰好装满dp[n][V]
      • 要求恰好装满dp[n][V] == -1 ? 0 : dp[n][V]
  • 滚动数组优化空间
    • 每次填值,只依赖上一行的值

      • 所以,理论上只需要两行一维数组,就可以解决问题
    • 可以一个一维数组就优化掉此问题

      • 但是如果从左往右遍历数组,会影响动态规划填值
        • 因为原本的填值过程,会依赖左上方的值
      • 此时,只需要从右往左遍历该数组,就不会影响动态规划的规程
        请添加图片描述

      请添加图片描述

    • 操作

      • 删除所有的横坐标
      • 修改一下j的遍历顺序
    • 注意不要去强行解释优化后的妆台表示以及状态转移方程,费时费力还没啥意义


3.代码实现

// v1.0
int main()
{int n = 0, V = 0;cin >> n >> V;vector<int> v(n + 1), w(n + 1);for(int i = 1; i <= n; i++){cin >> v[i] >> w[i];}vector<vector<int>> dp(n + 1, vector<int>(V + 1));// Q1for(int i = 1; i <= n; i++){for(int j = 1; j <= V; j++){dp[i][j] = dp[i - 1][j];if(j >= v[i]){dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i]] + w[i]);}}}cout << dp[n][V] << endl;// Q2dp.resize(n + 1, vector<int>(V + 1));for(int i = 1; i <= V; i++){dp[0][i] = -1;}for(int i = 1; i <= n; i++){for(int j = 1; j <= V; j++){dp[i][j] = dp[i - 1][j];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]);}}}cout << (dp[n][V] == -1 ? 0 : dp[n][V]) << endl;return 0;
}
-----------------------------------------------------------------------------
// v2.0 滚动数组优化
int main()
{int n = 0, V = 0;cin >> n >> V;vector<int> v(n + 1), w(n + 1);for(int i = 1; i <= n; i++){cin >> v[i] >> w[i];}vector<int> dp(V + 1);// Q1for(int i = 1; i <= n; i++){for(int j = V; j >= v[i]; j--){dp[j] = max(dp[j], dp[j - v[i]] + w[i]);}}cout << dp[V] << endl;// Q2dp.resize(V + 1, 0);for(int i = 1; i <= V; i++){dp[i] = -1;}for(int i = 1; i <= n; i++){for(int j = V; j >= v[i]; j--){if(dp[j - v[i]] != -1){dp[j] = max(dp[j], dp[j - v[i]] + w[i]);}}}cout << (dp[V] == -1 ? 0 : dp[V]) << endl;return 0;
}

2.分割等和子集

1.题目链接

  • 分割等和子集

2.算法原理详解

  • 问题转化:在数组中选择一些数出来,让这些数的和等于sum / 2 --> 01背包
  • 思路
    • 确定状态表示 -> dp[i][j]的含义

      • dp[i]j]:从前i个数中****,所有的选法中,能否凑成j这个数
    • 推导状态转移方程:根据最后一个位置的情况,分情况讨论

      • dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]]
        请添加图片描述
    • 初始化:

      • 多开一行及一列虚拟结点
        请添加图片描述
    • 确定填表顺序:从上往下

    • 确定返回值:dp[n][sum / 2]

  • 滚动数字优化同[模板] 背包

3.代码实现

// v1.0
bool canPartition(vector<int>& nums) 
{int n = nums.size(), sum = 0;for(auto& x : nums){sum += x;}if(sum % 2) return false;int aim = sum / 2;vector<vector<bool>> dp(n + 1, vector<bool>(aim + 1));// Initfor(int i = 1; i <= n; i++){dp[i][0] = true;}// DPfor(int i = 1; i <= n; i++){for(int j = 1; j <= aim; j++){dp[i][j] = dp[i - 1][j];if(j >= nums[i - 1]){dp[i][j] = dp[i][j] || dp[i - 1][j - nums[i - 1]];}}}return dp[n][aim];
}
----------------------------------------------------------------------
// v2.0 滚动数组优化
bool canPartition(vector<int>& nums) 
{int n = nums.size(), sum = 0;for(auto& x : nums){sum += x;}if(sum % 2) return false;int aim = sum / 2;vector<bool> dp(aim + 1);                dp[0] = true;// DPfor(int i = 1; i <= n; i++){for(int j = aim; j >= nums[i - 1]; j--){dp[j] = dp[j] || dp[j - nums[i - 1]];}}return dp[aim];
}

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

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

相关文章

JDBC编程

一. 概念 概念理解: 1) API 全称为"应用程序编程接口", 把这个词理解成"一组类"/"一组方法", 都是现成的(别的大佬写好的), 可以直接进行调用, 就可以实现一些效果 对于java来说, java提供了"标准库", 叫做标准库的API, 你只要安装…

PDF 文件的解析

1、文本 PDF 的解析 1.1、文本的提取 进行文本提取的 Python 库包括&#xff1a;pdfminer.six、PyMuPDF、PyPDF2 和 pdfplumber&#xff0c;效果最好的是 PyMuPDF&#xff0c;PyMuPDF 在进行文本提取时能够最大限度地保留 PDF 的阅读顺序&#xff0c;这对于双栏 PDF 文件的抽…

一分钟学习数据安全—自主管理身份SSI加密技术

上篇介绍了SSI的架构。架构之后&#xff0c;我们要了解一下SSI发展的驱动力&#xff1a;加密技术。现代数字通信离不开数学和计算机科学&#xff0c;加密技术也源于此。加密技术使区块链和分布式账本得以实现&#xff0c;也使SSI成为可能。 以下我们就概览一下SSI基础架构中涉及…

【Java毕业设计】基于JavaWeb的旅游论坛管理系统

文章目录 摘 要目 录1 概述1.1 研究背景及意义1.2 国内外研究现状1.3 拟研究内容1.4 系统开发技术1.4.1 Java编程语言1.4.2 vue技术1.4.3 MySQL数据库1.4.4 B/S结构1.4.5 Spring Boot框架 2 系统需求分析2.1 可行性分析2.2 系统流程2.2.1 操作流程2.2.2 登录流程2.2.3 删除信息…

基于Springboot+vue实现的汽车服务管理系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

6.6SSH的运用

ssh远程管理 ssh是一种安全通道协议&#xff0c;用来实现字符界面的远程登录。远程复制&#xff0c;远程文本传输。 ssh对通信双方的数据进行了加密 用户名和密码登录 密钥对认证方式&#xff08;可以实现免密登录&#xff09; ssh 22 网络层 传输层 数据传输的过程中是加密的 …

鸿蒙全栈开发-浅谈鸿蒙~线程模型

前言 如果你现在正巧在找工作&#xff0c;或者琢磨着换个职业跑道&#xff0c;鸿蒙开发绝对值得你考虑一下。 为啥&#xff1f;理由很简单&#xff1a; 市场需求大&#xff1a;鸿蒙生态还在持续扩张&#xff0c;应用开发、系统优化、技术支持等岗位需求旺盛&#xff0c;找工作…

聊聊二叉堆、红黑树、时间轮在定时任务中的应用

定时任务作为常用的一种调度方式&#xff0c;在各大系统得到了广泛的应用。 笔者也曾写过两篇关于定时任务框架介绍的文章&#xff1a; 《介绍一下,spring cloud下的另一种定时任务解决方案》《四叉堆在GO中的应用-定时任务timer》 之前都是以如何使用为主&#xff0c;这次从…

SOA主要协议和规范

Web服务作为实现SOA中服务的最主要手段。首先来了解Web Service相关的标准。它们大多以“WS-”作为名字的前缀&#xff0c;所以统称“WS-*”。Web服务最基本的协议包括UDDI、WSDL和SOAP&#xff0c;通过它们&#xff0c;可以提供直接而又简单的Web Service支持&#xff0c;如图…

此表单不安全,因此系统已关闭自动填充功能

问题截图&#xff1a; 截图就不放了&#xff0c;公司的系统不方便&#xff0c;就是form表单会有个提示“此表单不安全&#xff0c;因此系统已关闭自动填充功能” 解决思路&#xff1a; 1、问题原因 使用https访问&#xff0c;但表单提交地址是http的 2、查看表单配置 表单…

VCS基本仿真

这里记录三种仿真方式&#xff1a; 第一种是将verilog文件一个一个敲在终端上进行仿真&#xff1b; 第二种是将多个verilog文件的文件路径整理在一个文件中&#xff0c;然后进行仿真&#xff1b; 第三种是利用makefile文件进行仿真&#xff1b; 以8位加法器为例&#xff1a; …

一句话说清HDMI ARC eARC功能和区别

HDMI&#xff1a; 高清多媒体接口&#xff0c;主要用于传输高清音视频信号&#xff0c;High Definition Multimedia Interface。 ARC: 音频回传通道&#xff0c;Audio Return Channel eARC: 增强型音频回传通道&#xff0c;第一个E是增强的意思&#xff0c;Enhanced Audio…

分布式数据库架构:从单实例到分布式,开发人员需及早掌握?

现在互联网应用已经普及,数据量不断增大。对淘宝、美团、百度等互联网业务来说,传统单实例数据库很难支撑其性能和存储的要求,所以分布式架构得到了很大发展。而开发人员、项目经理,一定要认识到数据库技术正在经历一场较大的变革,及早掌握好分布式架构设计,帮助公司从古…

计网期末复习指南(六):应用层(DNS、FTP、URL、HTTP、SMTP、POP3)

前言&#xff1a;本系列文章旨在通过TCP/IP协议簇自下而上的梳理大致的知识点&#xff0c;从计算机网络体系结构出发到应用层&#xff0c;每一个协议层通过一篇文章进行总结&#xff0c;本系列正在持续更新中... 计网期末复习指南&#xff08;一&#xff09;&#xff1a;计算…

学习周报:文献阅读+Fluent案例+Fluent相关算法学习

目录 摘要 Abstract 文献阅读&#xff1a;求解正逆运动波问题的物理信息神经网络 文献摘要 讨论|结论 理论基础 KWM&#xff08;运动波动方程&#xff09; Hard constraint &#xff08;硬约束方式&#xff09; 具有重新分布的搭配点的PINN 具有停止梯度的分数阶方程 …

Gradio 案例——将文本文件转为词云图

文章目录 Gradio 案例——将文本文件转为词云图界面截图依赖安装项目目录结构代码 Gradio 案例——将文本文件转为词云图 利用 word_cloud 库&#xff0c;将文本文件转为词云图更完整、丰富的示例项目见 GitHub - AlionSSS/wordcloud-webui: The web UI for word_cloud(text t…

算法导论实战(三)(算法导论习题第二十四章)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;算法启示录 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 前言 第二十四章 24.1-3 24.1-4 2…

DVWA-XSS(Reflected)

反射型XSS可以用来窃取cookie Low 输入1111进行测试&#xff0c;发现1111被打印 输入<script>alert(document.cookie)</script>&#xff0c;出现弹窗&#xff0c;获得cookie Medium 查看后端代码&#xff0c;发现对<script>进行了转义&#xff0c;但是…

【UML用户指南】-10-对高级结构建模-高级类

目录 1、类目 2、高级类 3、可见性 4、实例范围和静态范围 5、抽象元素、叶子元素和多态性元素 6、多重性 7、属性 8、操作 9、模板类 10、标准元素 1、类目 类目 &#xff08;classifier&#xff09;是描述结构特征和行为特征的机制。类目包括类、关联、接口、数据类…

nvm安装使用

什么是 node.js&#xff1f;&#xff1a; Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;可以在服务器端运行 JavaScript。由于其非阻塞 I/O 模型和事件驱动架构&#xff0c;Node.js 非常适合构建高并发、低延迟的应用程序。随着 Node.js 的不断发展&…