完全背包(从二维数组到一维滚动数组)

完全背包 :有一个背包的容积为V,有N个物品,每个物品的体积为v[i],权重为w[i],每个物品可以取无限次放入背包中,背包所有物品权重和最大是多少?

背包最大重量为4,每个物品有无限个,物品的重量和价值如下:

重量价值
物品0115
物品1320
物品2430

二维dp数组完全背包

1. 确定dp数组以及下标的含义

dp[i][j]数组表示从前i个物品中任意取,放进容量为j的背包中所得到的物品的最大价值。

2. 确定递推公式

有两个方向推出来dp[i][j]:

  • 不放物品i:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]

    (其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。)

  • 放物品i:由dp[i][j - weight[i]]推出,注意这里和01背包的区别,因为可以重复放物品i,所以是dp[i][j - weight[i]],表示背包容量为j - weight[i]的时候任取物品i的最大价值

  • 递归公式 dp[i][j] = max(dp[i - 1][j], dp[i][j - weight[i]] + value[i]);

    • 如果物品i的重量大于背包容量j时,背包放不下,就不能选择物品i,dp[i][j] = dp[i - 1][j]
    • 如果物品i的重量小于等于背包容量j时,dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - weight[i]] + value[i])

3. dp数组如何初始化

关于初始化,一定要和dp数组的定义一致。

两种初始化情况:

  • 背包容量j为0,不管选择哪些物品,所得到的物品最大价值一定为0,所以dp[i][0] = 0
  • 物品数量为0时,不论背包容量多大,所得到的物品最大价值一定为0,所以dp[0][j] = 0
dp[i][j](物品\背包)01234
无物品00000
物品00
物品10
物品20

4. 确定遍历顺序

有两个遍历的维度:物品和背包,那么问题来了,先遍历物品还是先遍历背包重量呢?

其实都可以,因为递推公式为dp[i][j] = dp[i - 1][j]dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - weight[i]] + value[i])这两种情况,不论哪种,dp[i - 1][j]dp[i][j - weight[i]]都在dp[i][j]的左上角方向,而两种遍历顺序都能够获取到dp[i][j]左上角方向的值,先遍历物品会更好理解

5. 举例推导dp数组

dp[i][j](物品\背包)01234
无物品00000
物品0(重量1,价值15)015304560
物品1(重量3,价值20)015304560
物品2(重量4,价值30)015304560

完整代码:

/*********************************************************************
完全背包
有n件物品和一个最多能背重量为w的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。
每件物品有无限个,即一个物品可以放入背包多次,求解将哪些物品装入背包里物品价值总和最大。
重量 价值
物品0	1	15
物品1	3	20
物品2	4	30
*********************************************************************/
#include <iostream>
#include <vector> 
#include <string>
#include <algorithm> 
using namespace std;// 先遍历物品,在遍历背包
int bag1(vector<int> weight, vector<int> value, int bagweight) {vector<vector<int>> dp(weight.size() + 1, vector<int>(bagweight + 1, 0));for (int i = 1; i <= weight.size(); i++){for (int j = 0; j <= bagweight; j++){	// 遍历背包if (j < weight[i - 1]){dp[i][j] = dp[i - 1][j];}else{// 注意这里跟01背包只有下面一个下标不同,那就是“放i”这个选择,因为是可以重复放的,所以是dp[i]dp[i][j] = max(dp[i - 1][j - 1], dp[i][j - weight[i - 1]] + value[i - 1]);}}}for (auto x : dp) {for (auto xx : x) {cout << xx << ' ';}cout << endl;}return dp[weight.size()][bagweight];
}int main(){vector<int> weight = { 1, 2, 3, 4 };vector<int> value = { 10, 21, 30, 43 };int bagweight = 5;int ret = bag1(weight, value, bagweight);cout << ret << endl;system("PAUSE");return 0;
}

一维滚动dp数组完全背包

1.确定dp数组以及下标的含义

dp[j]表示容量为j的背包中所得到的物品的最大价值。

2. 确定递推公式

递推公式变为dp[j] = max(dp[j], dp[j - weight[i]] + value[i])

3. dp数组如何初始化

dp[0] = 0即可

4. 确定遍历顺序

01背包内嵌的循环是从大到小遍历,为了保证每个物品仅被添加一次;而完全背包的物品是可以添加多次的,所以要从小到大去遍历

5. 举例推导dp数组

完整代码:

/*********************************************************************
完全背包
有n件物品和一个最多能背重量为w的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。
每件物品有无限个,即一个物品可以放入背包多次,求解将哪些物品装入背包里物品价值总和最大。
重量 价值
物品0	1	15
物品1	3	20
物品2	4	30
*********************************************************************/
#include <iostream>
#include <vector> 
#include <string>
#include <algorithm> 
using namespace std;// 先遍历物品,在遍历背包
int bag1(vector<int> weight, vector<int> value, int bagweight) {vector<int> dp(bagweight + 1, 0);// 先遍历物品,再遍历背包for (int i = 0; i < weight.size(); i++) { // 遍历物品for (int j = weight[i]; j <= bagweight; j++) { // 遍历背包容量dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}}return dp[bagweight];
}int main(){vector<int> weight = { 1, 2, 3, 4 };vector<int> value = { 10, 21, 30, 43 };int bagweight = 5;int ret = bag1(weight, value, bagweight);cout << ret << endl;system("PAUSE");return 0;
}

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

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

相关文章

填充每个节点的下一个右侧节点Ⅱ-力扣

本题如果使用BFS去层序遍历&#xff0c;代码和 填充每个节点的下一个右侧节点 题没有任何区别。但是使用已经建立好的next链表去做&#xff0c;则需要考虑到next指向的节点子节点是否为空的可能。 class Solution { public:Node* connect(Node* root) {if(root nullptr){retu…

城镇污水处理设施运维服务认证

初次申请认证时需提交的文件/资料 1、通用文件/资料(证明文件复印件需签字盖公章) ☐ 营业执照复印件、统一社会信用代码/组织机构代码证复印件 ☐ 增值税一般纳税人资格证复印件&#xff0c;或其他增值税一般纳税人资格认定文件复印件 ☐ 资质 或 许可证 复印件&#x…

RT-Thread

RT-Thread RT-Thread 版权属于上海睿赛德电子科技有限公司&#xff0c;于 2006年 1月首次发布&#xff0c;初始版 本号为0.1.0&#xff0c;经过 10来年的发展&#xff0c;如今主版本号已经升级到3.0&#xff0c;累计开发者达到数百万&#xff0c; 在各行各业产品中装机量达到了…

C++ 并发编程指南(5)线程状态及切换

文章目录 一、多线程状态及切换1、线程状态2、状态切换 前言&#xff1a; C中的线程状态及切换是操作系统和C线程库&#xff08;如POSIX线程或C11及之后的<thread>库&#xff09;共同管理的。线程的状态和切换是多线程编程中的重要概念&#xff0c;下面将简要介绍C线程的…

大数据的数据变换与价值提炼

大数据的数据变换与价值提炼是指将原始的大数据进行分析和处理&#xff0c;从中提取出有用的信息和洞察&#xff0c;并转化为可以支持决策和创新的价值。这个过程通常包括以下几个步骤&#xff1a; 数据清洗和整理&#xff1a;原始的大数据通常会包含大量的噪音和冗余信息&…

大模型SFT

简介 supervised fine-tuning的缩写&#xff0c;即有监督的微调。如应用到一个新的场景&#xff0c;就可以使用SFT 开发流程 设计prompt选取llm模型制作数据集&#xff0c;子任务1k就可以了。内容要丰富。风格格式统一&#xff1b;尽量不加入新知识SFT微调 疑问 SFT很难学…

【Linux取经路】守护进程

文章目录 一、前台进程和后台进程二、Linux 的进程间关系三、setsid——将当前进程设置为守护进程四、daemon——设置为守护进程五、结语 一、前台进程和后台进程 Linux 中每一次用户登录都是一个 session&#xff0c;一个 session 中只能有一个前台进程在运行&#xff0c;键盘…

国产工业级实时数据库

项目功能描述 Mars数据库的核心功能在于其能够高效地处理来自工业现场的大量传感器数据。它通过简化的可视化配置&#xff0c;允许用户轻松接入各种传感器&#xff0c;并进行数据记录和逻辑处理。Mars数据库在单机模式下支持高达120万个传感器信号的接入&#xff0c;而其分布式…

Python Excel 指定内容修改

需求描述 在处理Excel 自动化时,财务部门经常有一个繁琐的场景,需要读取分发的Excel文件内容复制到汇总Excel文件对应的单元格内,如下图所示: 这种需求可以延申为,财务同事制作一个模板,将模板发送给各员工,财务同事需收取邮件将员工填写的excel文件下载到本机,再类似…

Java Web学习笔记15——DOM对象

DOM&#xff1a; 概念&#xff1a;Document Object Model&#xff1a; 文档对象模型 将标记语言的各个组成部分封装为对应的对象&#xff1a; Document: 整个文档对象 Element&#xff1a;元素对象 Attribute&#xff1a; 属性对象 Text&#xff1a;文本对象 Comment&a…

c++11 constexpr关键字

constexpr 是 C11 引入的一个关键字&#xff0c;它允许在编译时计算表达式的值&#xff0c;并将这些值存储在程序的常量部分中。这意味着 constexpr 变量和函数可以在编译时进行求值&#xff0c;从而避免了运行时的开销。 constexpr变量 constexpr 变量必须在编译时初始化&am…

如何使用ChatGPT写出爆款自媒体短视频文案

一、引言 自媒体时代&#xff0c;短视频的爆款文案往往能决定内容的传播效果。在众多工具中&#xff0c;ChatGPT以其强大的语言模型和多样化的应用场景&#xff0c;成为创作者的得力助手。今天我将分享如何使用ChatGPT来撰写引人注意的短视频文案&#xff0c;助你的内容一飞冲…

【Linux取经路】信号的发送与保存

文章目录 一、重新理解发送信号二、信号的保存、阻塞信号的概念三、信号集操作函数3.1 sigprocmask3.2 sigpending 四、阻塞信号代码验证五、结语 一、重新理解发送信号 进程通过位图来实现对普通信号&#xff08;1-31号信号&#xff09;的保存&#xff0c;该位图保存在进程的…

冯喜运:6.7今日黄金原油行情分析及独家操作策略

【黄金消息面分析】&#xff1a;周三&#xff08;6月5日&#xff09;&#xff0c;金价回升逾1.2%&#xff0c;收盘报每盎司2,355.49美元&#xff0c;全面收复前一交易日的跌幅。周三当天前公布的美国民间就业数据弱于预期&#xff0c;增强了美联储将在今年晚些时候降息的预期&a…

多表连接查询和子查询

一、连接查询 连接查询是SQL语言最强大的功能之一&#xff0c;它可以执行查询时动态的将表连接起来&#xff0c;然后从中查询数据。 1.1、连接两表的方法 在SQL中连接两表可以有两种方法&#xff0c;一种是无连接规则连接&#xff0c;另一种是有连接规则连接。 无连接规则连…

PbootCms微信小程序官网模版/企业官网/社交电商官网/网络工作室/软件公司官网

在数字化时代&#xff0c;企业网站已成为吸引潜在客户、提升企业形象、和扩大品牌影响力的必备工具。因此&#xff0c;一个优秀的企业网站模板显得尤为重要。 企业官网的内容框架通常都包含企业形象、产品或服务类型、信息展示等部分&#xff0c;设计师需要借助和企业形象契合…

初学者如何对大模型进行微调?

粗略地说&#xff0c;大模型训练有四个主要阶段&#xff1a;预训练、有监督微调、奖励建模、强化学习。 预训练消耗的时间占据了整个训练pipeline的99%&#xff0c;其他三个阶段是微调阶段&#xff0c;更多地遵循少量 GPU 和数小时或数天的路线。预训练对于算力和数据的要求非…

【vue3|第6期】如何正确地更新和替换响应式对象reactive

日期&#xff1a;2024年6月5日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

区间预测 | Matlab实现QRCNN-GRU-Attention分位数回归卷积门控循环单元注意力机制时序区间预测

区间预测 | Matlab实现QRCNN-GRU-Attention分位数回归卷积门控循环单元注意力机制时序区间预测 目录 区间预测 | Matlab实现QRCNN-GRU-Attention分位数回归卷积门控循环单元注意力机制时序区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现QRCNN-GRU-…

eNSP学习——配置RIP的版本兼容、定时器和协议优先级

目录 主要命令 原理概述 实验内容 实验拓扑 实验目的 实验编址 实验步骤 1、基本配置 2、配置RIP协议的版本兼容 3、配置RIP的定时器 4&#xff0e;配置RIP协议优先级 需要eNSP各种配置命令的点击链接自取&#xff1a;华为&#xff45;NSP各种设备配置命令大全PDF版…