动态规划-背包问题进阶-完全背包和多重背包

我们之前讲过01背包,现在我们讲讲背包问题的进阶,先说完全背包。

完全背包相对于01背包的区别在于商店每个物品的无限性,就是可以被拿无数次,而01背包每个物品只能拿一次

完全背包问题中,每个物品可以选择无限次,因此对于背包的每个容量,我们需要考虑选择当前物品的各种个数来取得最大价值。这就需要在动态规划的过程中,以背包的容量为维度,对每个容量都不断更新最大价值。

使用一维数组作为动态规划的状态转移数组可以简化实现。假设当前背包的容量为 j,物品的价格为 v,重量为 wdp[j] 表示当前容量为 j 时的最大价值。状态转移方程可以表示为:

dp[j] = max(dp[j], dp[j - w] + v)

在每次更新当前物品的最大价值时,我们需要考虑选择不同的物品个数,即选择 w 的倍数。因此,我们只需要维护一个一维数组 dp,它的长度为背包的容量,代表不同容量下的最大价值。

每个容量 j 对应的最大价值 dp[j] 都可以由之前的状态 dp[j-w], dp[j-2w], ... 推导出来。这样,可以在一次遍历中更新所有的背包容量,而不需要维护一个二维数组。

当用一维数组进行状态转移时,可以通过正向的遍历顺序来更新数组的值,确保在计算当前状态时所需的前一状态已经被计算过。这样,通过不断更新 dp[j - w] 可以得到正确的最大价值。

完全背包的大致模板

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;int knapsack(int N, int V, vector<int>& wt, vector<int>& val) {// 初始化dp数组,表示背包在容量为i时的最大价值vector<int> dp(V + 1, 0);// 逐个考虑每个物品for (int i = 0; i < N; ++i) {// 完全背包,正向遍历容量for (int j = wt[i]; j <= V; ++j) {dp[j] = max(dp[j], dp[j - wt[i]] + val[i]);}}return dp[V];
}int main() {int N = 3; // 物品的数量int V = 5; // 背包的容量vector<int> wt = {2, 3, 4}; // 物品的重量vector<int> val = {3, 4, 5}; // 物品的价值cout << knapsack(N, V, wt, val) << endl;return 0;
}

为了加深对完全背包的印象,我们通过一道例题来深刻理解下,

小明有一个容量为 VV 的背包。

这天他去商场购物,商场一共有 NN 种物品,第 ii 种物品的体积为 wiwi​,价值为 vivi​,每种物品都有无限多个。

小明想知道在购买的物品总体积不超过 VV 的情况下所能获得的最大价值为多少,请你帮他算算。

这道题完全可以套用以上的模板,但是上述示例模板较为冗长,这里精简代码为:

#include <iostream>
using namespace std;
const int N = 1e3 + 2;
int dp[N];
int main()
{int n,m;cin>>n>>m;for(int i= 1;i<=n;i++){int w,v;cin>>w>>v;for(int j=w;j<=m;j++){dp[j] = max(dp[j] , dp[j - w] + v);}}cout << dp[m] << endl;return 0;
}

接下来,我们讲讲多重背包,多重背包和01背包区别同样是在物品可选择个数上面,多重背包的某个物品最多可以拿k个,一般在解决这类问题时,我们一般在原有的01背包的模板的第二层for循环之前进行while(k--)操作,就是每个物品更新k次。写代码为:

#include <iostream>
using namespace std;
const int N = 105;
int dp[N];
int main()
{int n,m;cin>> n >> m;for(int i = 1; i <= n;i++){int w,v,s;cin>>w>>v >> s;while(s--)
{for(int j= m;j>=w;j--){dp[j] = max(dp[j],dp[j  - w] + v);}
}}cout << dp[m] << endl;return 0;
}

这样在较小的输入情况下可以通过,但是不具有普遍性,我们通常采用单调队列的优化来解决多重背包的一般性问题。

以下为模板:
 

#include <iostream>
#include <cstring>
using namespace std;const int MAXN = 1005;
const int MAXW = 20005;
int weight[MAXN];
int value[MAXN];
int count[MAXN];
int dp[MAXW];void MultipleKnapsack(int weight[], int value[], int count[], int n, int W) {memset(dp, 0, sizeof(dp));for (int i = 0; i < n; i++) {for (int k = 1; k <= count[i]; k <<= 1) {for (int j = W; j >= k * weight[i]; j--) {dp[j] = max(dp[j], dp[j - k * weight[i]] + k * value[i]);}count[i] -= k;}if (count[i] > 0) {for (int j = W; j >= count[i] * weight[i]; j--) {dp[j] = max(dp[j], dp[j - count[i] * weight[i]] + count[i] * value[i]);}}}
}int main() {int n, W;cin>>n>>W;for (int i = 0; i < n; i++) {cin >> weight[i] >> value[i] >> count[i];}MultipleKnapsack(weight, value, count, n, W);cout  << dp[W] << endl;return 0;
}

现在讲完了多重背包和完全背包,下次我们会讲背包问题的最后两种情况,二维费用背包和分组背包,敬请期待!

原完全背包板子题链接:

https://www.lanqiao.cn/problems/1175/learning/?page=1&first_category_id=1&name=%E5%B0%8F%E6%98%8E%E7%9A%84%E8%83%8C%E5%8C%852
原多重背包(未优化)板子题链接:
https://www.lanqiao.cn/problems/1176/learning/?page=1&first_category_id=1&name=%E5%B0%8F%E6%98%8E%E7%9A%84%E8%83%8C%E5%8C%853

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

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

相关文章

【二叉树】遍历及构造

1. 定义 二叉树是一种树形数据结构&#xff0c;由节点组成&#xff0c;每个节点最多有两个子节点&#xff0c;分别为左子节点和右子节点。二叉树具有以下性质&#xff1a; 每个节点最多有两个子节点&#xff0c;称为左子节点和右子节点。 左子节点和右子节点可以为空&#xff0…

命令执行讲解和函数

命令执行漏洞简介 命令执行漏洞产生原因 应用未对用户输入做严格得检查过滤&#xff0c;导致用户输入得参数被当成命令来执行 命令执行漏洞的危害 1.继承Web服务程序的权限去执行系统命会或读写文件 2.反弹shell&#xff0c;获得目标服务器的权限 3.进一步内网渗透 远程代…

泛微e-office系统存在敏感信息泄露 附POC软件

免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 1. 泛微e-office系统简介 微信公众号搜索:南风漏洞复…

mysql 锁详解

目录 前言 一、全局锁 二、表级锁 三、行锁 前言 为什么要设计锁&#xff0c;锁设计初衷是为了解决多线程下并发问题。出现并发的时候用锁进行数据同步&#xff0c;避免因并发造成了数据错误(数据覆盖)。可见锁的重要性&#xff0c;并不是所有的数据库都有锁。比如Redis&a…

什么是CODESYS开发系统

CODESYS是一种用于工业自动化领域的开发系统软件&#xff0c;提供了一个完整集成的开发环境。该软件由德国CODESYS GmbH&#xff08;原 3S-Smart Software Solutions GmbH&#xff09;公司开发&#xff0c;其最新版本为CODESYS V3。 CODESYS开发系统具有多种特性和优点。首先&a…

⭐北邮复试刷题105. 从前序与中序遍历序列构造二叉树__递归分治 (力扣每日一题)

105. 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,…

Rocky 8.9 Kubespray v2.24.0 在线部署 kubernetes v1.28.6 集群

文章目录 1. 简介2. 预备条件3. 基础配置3.1 配置hostname3.2 配置互信 4. 配置部署环境4.1 在线安装docker4.2 启动容器 kubespray4.3 编写 inventory.ini4.4 关闭防火墙、swap、selinux4.5 配置内核模块 5. 部署6. 集群检查 1. 简介 kubespray​ 是一个用于部署和管理 Kuber…

抽象方法与设计模式

抽象方法与设计模式 设计模式的六大原则工厂模式单例模式建造者模式过滤器模式装饰器模式享元模式责任链模式模板模式 真正的屎山不是初级程序员写的巨量胶水代码&#xff0c;而是没学明白抽象的程序员写的大量设计模式耦合形成的。你甚至不理解为什么当初的创作者需要使用到这…

基于postMessage和BroadcastChannel实现浏览器跨Tab窗口通信的方法介绍

文章目录 一、Broadcast Channel1、创建实例2、监听消息3、发送消息4、关闭5、示例演示5.1、主控页面5.2、受控页面 二、postMessage1、语法1.1、targetWindow1.2、message1.3、targetOrigin1.4、transfer&#xff08;可选的&#xff09; 2、示例演示2.1、parent页面2.2、child…

Elsevier投稿录用后的一些疑问

在elsevier投稿被录用之后&#xff0c;会收到好几个邮件&#xff1a; 第一封邮件是给你一个在线修改稿子的网站&#xff0c;让你核实作者&#xff0c;文献等等的信息&#xff0c;以及编辑做的修改&#xff0c;要注意的是有几个query问题是必须回答的。然后你在线修改完提交就可…

CF1468J Road Reform 题解

CF1468J Road Reform 题解 link CF1468J Road Reform 题面翻译 给定一个有 n n n 个节点&#xff0c; m m m 条无向带权边的图&#xff0c;和一个参数 k k k&#xff0c;第 i i i 条边权值为 s i s_i si​。 现在你要保留这个图中的 n − 1 n-1 n−1 条边使得这个图变…

java导出动态下拉框excel模板

1.原始模板 2.导出模板,下拉框为数据库中得到动态数据 public void downloadTemplate(HttpServletResponse response) throws IOException {// 所有部门List<String, String> departments expertManageMapper.selectAllDepartment();//所有职位List<String, String&g…

前端关于Vue跳转外部链接(百度为例)

一定要加这句 window.location.href http://www.baidu.com/s?wd this.wd;关于Vue跳转外部链接&#xff08;百度为例&#xff09;_vue3.2 点击按钮 router.resolve 跳转 百度-CSDN博客 <img src"./hd1.jpg" width"200px" height"100px" c…

模块 time:时间和日期处理

MicroPython内置模块 time&#xff1a;时间和日期处理 MicroPython的内置模块time是一个用于处理时间相关功能的模块&#xff0c;它实现了CPython模块的一个子集&#xff0c;但也有一些特殊的特点和限制。本文将从以下几个方面介绍time模块的主要特点、应用场景&#xff0c;以…

基于Java (spring-boot)的社区物业管理系统

一、项目介绍 本系统共分为两个角色&#xff1a;管理员和业主。 主要功能有&#xff0c;核心业务处理&#xff0c;基础信息管理&#xff0c;数据统计分析 核心业务处理&#xff1a;车位收费管理&#xff0c;物业收费管理&#xff0c;投诉信息管理&#xff0c;保修信息管理。 …

Top-N 泛型工具类

一、代码实现 public class TopNUtil<E extends Comparable<E>> {private final PriorityQueue<E> priorityQueue;private final int n;/*** 构造 Top-N*/public TopNUtil(int size) {if (size < 0) {throw new IllegalArgumentException("Top-N si…

嵌入式学习day22 Linux

文件IO: 1. lseek off_t lseek(int fd, off_t offset, int whence); 功能: 重新设定文件描述符的偏移量 参数: fd:文件描述符 offset:偏移量 whence: SEEK_SET 文件开头 …

代码随想录三刷day04

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣209. 长度最小的子数组二、力扣904. 水果成篮三、力扣76. 最小覆盖子串 前言 接下来就开始介绍数组操作中另一个重要的方法&#xff1a;滑动窗口。 所谓…

C++从入门到精通 第十四章(STL容器)【下】

七、list容器 1、list的基本概念 &#xff08;1&#xff09;list的功能是将数据进行链式存储&#xff0c;对应数据结构中的链表&#xff0c;链表是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接实现的。 &#xff08;2&#xff…

《VitePress 简易速速上手小册》第2章:Markdown 与页面创建(2024 最新版)

文章目录 2.1 Markdown 基础及扩展2.1.1 基础知识点解析2.1.2 重点案例&#xff1a;技术博客2.1.3 拓展案例 1&#xff1a;食谱分享2.1.4 拓展案例 2&#xff1a;个人旅行日记 2.2 页面结构与布局设计2.2.1 基础知识点解析2.2.2 重点案例&#xff1a;公司官网2.2.3 拓展案例 1&…