解决0-1背包问题(方案一):二维dp数组

news2024/11/23 20:12:35

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

dp[i][j]表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

(1)不放物品i

例如:当背包的容量是1kg,此时物品1和物品2都是无法放进去的。而物品0是可以放进背包的

那么此种情况下:

物品0,产生的最大的价值为15

物品1,产生的最大的价值和前面相同,也就是15

物品2,产生的最大的价值和前面相同,也就是15

观察二维表格,以及分析,我们可以这样表示:dp[i-1][j]

思考dp[i-1][j]表示什么意思呢?

看表格的 j=0,这一列,正是上文所述的这种情况。也就是背包的容量为 j 的时候,可以放入物品i 或者不能放入物品i 的所能产生的最大的价值!

思考:不能放入物品i时,如何计算其产生的最大价值呢?

只要和前面的值相同即可。相当于 copy 下来。

例如物品1(3kg)放不进容量小于3kg的背包。也就是背包容量为1kg,2kg时,无法放入物品1,那么此时这种情况如何计算最大价值呢?很简单,就是和前面的值相同即可。也就是和物品0产生的最大价值相同。

同理,物品2(4kg)放不进容量小于4kg的背包。也就是背包容量为1kg,2kg,3kg时,无法放入物品2,那么此时和物品1产生的最大价值相同即可。

思考:若能放入物品i呢?

分成两种方案:

【方案一】:放入物品i 能产生的最大价值

【方案二】:不放入物品i能产生的最大价值

选取最大价值即可~

例如:当背包的容量是4kg,可以只放入物品2(4kg),但是产生的价值未必是最大的。此时我们思考一下如果不放入物品2,而是放入其他的物品,计算其重量之和为4kg所能产生的价值。

若不放入物品2,可以有如下思路:

① 只放入物品0(1kg),产生价值15

② 只放入物品1(3kg),产生价值20

③ 先放入物品1(3kg),剩余的1kg的容量,用来放入物品0(1kg),总该产生价值35

那么我们如何实现③这种方案呢?

显然,4kg的容量是可以放入物品1(3kg)并可知其产生的价值为20,那么此时可以计算出剩余容量(1kg),接着在表格中找出1kg能产生的最大价值为15,然后求其价值总和为35。

观察二维表格,以及分析,我们可以这样表示:

dp[i-1][j-weight[i]] + value[i]

(2)放入物品i

例如:当背包的容量是4kg,只放入物品2(4kg),产生价值为30

我们可以发现,应该取 max(不放物品i的最大价值,所剩容量能产生的最大价值 + 放物品i的价值)

上文提及不放物品2,而是放入其他物品时,产生的最大价值为35(也就是放入物品0和物品1所产生的最大价值)。35>30。此时我们便可更新背包的容量是4kg时所能 产生的最大价值为35。

最大价值:dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]] + value[i])

(3)动规五部曲:

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

dp[i][j]表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

2.确定递推公式

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

由dp[i-1][j-weight[i]]推出,dp[i-1][j-weight[i]]为背包容量为j-weight[i]的时候不放物品i的最大价值,那么dp[i-1][j-weight[i]] + value[i](物品i的价值),就是背包放物品i得到的最大价值

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

3.dp数组如何初始化

【注意】关于初始化,一定要和dp数组的定义吻合,否则到递推公式的时候会乱掉。

从定义出发,若背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。

状态转移方程dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]] + value[i]);可以看出i是由i-1推导出来,那么i为0的时候就一定要初始化。

dp[0][j],即i为0,存放编号为0的物品的时候,各个容量的背包所能存放的最大价值很明显,当j<weight[0]的时候,dp[0][j]应该是0,因为背包容量比编号0的物品重量小。当j>=weight[0]时,dp[0][j]应该是value[0],因为背包容量足够放编号0物品。

dp[0][j] 和 dp[i][0] 都已经初始化了,那么其他下标应该初始化为多少呢?

其实从递归公式:dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]] + value[i]);可以看出dp[i][j]是由左上方数值推导出来,那么其他下标初始为什么数值都可以,因为都会被覆盖

初始-1,初始-2,初始100,都可以!

但一开始统一把dp数组统一初始化为0,更方便一些。

dp[i][j]表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少 

4.确定遍历顺序

有两个遍历的维度:物品与背包重量

思考🤔:请问是先遍历物品还是先遍历背包重量呢?

其实都可以!!!但是先遍历物品更加容易理解!!!

// weight数组的大小,就是物品的个数
for(int i=1;i<weight.size();i++) { // 遍历物品
    for(int j=0;j<=bagWeight;j++)  {
        if(j < weight[i]) dp[i][j] = dp[i-1][j];
        else dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]] + value[i]);
    }
}

5.举例推导dp数组

完整代码:

#include <iostream>
#include <vector>
using namespace std;

void test_1_wei_bag_problem() {
	vector<int> weight = { 1,3,4 };
	vector<int> value = { 15,20,30 };
	int bagWeight = 4;

	// 初始化
	vector<int> dp(bagWeight + 1, 0);
	print(dp,bagWeight);
	for (int i = 0; i < weight.size(); i++) { // 遍历物品
		for (int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量
			dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
		}
	}
	cout << dp[bagWeight] << endl;
}

int main() {
	test_1_wei_bag_problem();
}

 思考

// 遍历过程
for(int i=1;i<weight.size();i++) { // 遍历物品
    for(int j=0;j<=bagWeight;j++) {
        if(j-weight[i] >= 0) {
            dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]] + value[i]);
        }
    }
}

其实就是省去了背包容量无法放下物品i的情况时候,和前面值一样的"copy"

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

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

相关文章

【前端】常用属性及实例

1. 盒子水平垂直居中 1&#xff09;flex布局实现水平垂直居中 <style>.box {background: yellow;width: 200px;height: 200px;/* 设置flex布局 */display: flex;/* 水平居中 */justify-content: center;/* 垂直居中 */align-items: center;}.col {margin: 1px;backgroun…

使用 queueMicrotask 创建微任务!

之前我们想尽一切办法来创建一个自定义的微任务&#xff0c;如 Promise.then、MutationObserver&#xff08;浏览器环境中的 API&#xff0c;用于监视 DOM 变动&#xff09;、async/await、process.nextTick&#xff08;仅Node.js支持&#xff0c;本质来说它不是事件循环的一部…

8+单基因+细胞凋亡+WGCNA+单细胞+实验验证

今天给同学们分享一篇单基因细胞凋亡WGCNA实验验证的生信文章“RASGRP2 is a potential immune-related biomarker and regulates mitochondrial-dependent apoptosis in lung adenocarcinoma”&#xff0c;这篇文章于2023年2月3日发表在Front Immunol期刊上&#xff0c;影响因…

JDK21新特性

JDK 21 于 2023 年 9 月 19 日正式发布。Oracle 提供GPL 下的生产就绪二进制文件&#xff1b;其他供应商的二进制文件也将很快推出。 Spring Boot 3.x 版本最低支持的 JDK 版本为 JDK 17&#xff0c;也就是说如果你还想用 JDK8的话&#xff0c;那能用的最高 Spring Boot 版本为…

按文件名称轻松管理文件!让文件管理更加高效!

文件管理是日常工作和生活中必不可少的一环&#xff0c;然而&#xff0c;面对众多的文件&#xff0c;如何快速找到所需文件&#xff0c;是一个具有挑战性的任务。现在&#xff0c;我们为您提供一种智能归类的解决方案&#xff0c;让您能够按文件名称轻松管理文件&#xff0c;让…

基于springboot+vue的高校专业实习管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

如何利用Arcgis进行地统计学分析(二):探索性数据分析

地统计学的相关介绍及概念参考上篇博客&#xff1a; 如何利用Arcgis进行地统计学分析&#xff08;一&#xff09;&#xff1a;地统计学分析概念及其分析流程_小咖~的博客-CSDN博客 探索性数据分析是为了让用户更深入地认识研究对象&#xff0c;从而对与其数据相关的问题做出更…

java:算法题(持续更新)

第一题&#xff1a;特征值计算 案例&#xff1a;定义一个int型的一维数组&#xff0c;包含10个元素&#xff0c;分别赋一些随机整数&#xff0c;然后求出所有元素的最大值&#xff0c;最小值&#xff0c;总和&#xff0c;平均值&#xff0c;并输出出来。要求&#xff1a;所有随…

【刷题篇】回溯算法(深度优先搜索(一))

文章目录 无重复字符串的排列组合员工的重要性图像渲染被围绕的区域 无重复字符串的排列组合 无重复字符串的排列组合。编写一种方法&#xff0c;计算某字符串的所有排列组合&#xff0c;字符串每个字符均不相同。 class Solution { public:void DFS(string &s,vector<s…

手撸列表数据内嵌动态th甘特图

需求如图&#xff1a;日期为后端返回的七天日期&#xff0c;这七天组成由甘特图内嵌展示。 解决思路&#xff1a;这个vue项目中el-table自带样式过多&#xff0c;且不方便动态渲染数据&#xff0c;所以用div模拟了&#xff0c;这里甘特图精度为半天所以用v-if判断了&#xff0…

echarts三柱图叠加三柱图解法

需求如图所示。 解决思路1&#xff1a;实际展示柱体魏三叠加柱的和&#xff0c;那么把每个和计算出来作为一个柱的数组&#xff08;此柱实际展示&#xff09;&#xff0c;为了tootip方便自定义取数据且不用每个都查询原始数据&#xff0c;做叠加柱为一般、严重、危急&#xff…

FastChat 大模型部署推理;Baichuan2-13B-Chat测试、chatglm2-6b测试

参考&#xff1a; https://github.com/lm-sys/FastChat https://blog.csdn.net/qq128252/article/details/132759107 ##安装 pip3 install "fschat[model_worker,webui]"1、chatglm2-6b测试 python3 -m fastchat.serve.cli --model-path ./chatglm2-6b --num-gpus …

【JVM内存区域及创建对象的过程】

文章目录 JVM内存区域及创建对象的过程JVM内存区域JDK1.6、1.7、1.8内存区域的变化&#xff1f;创建对象的过程类的声明周期&#xff1a; JVM内存区域及创建对象的过程 JVM内存区域 JVM 内存区域最粗略的划分可以分为 堆 和栈&#xff0c;当然&#xff0c;按照虚拟机规范&…

Vue页面快速使用阿里巴巴矢量图标库

前面我已经写个一篇文章 阿里巴巴矢量图标如何使用_turbo夏日漱石的博客-CSDN博客 这篇文章非常详细地讲解了在html页面中如何使用阿里巴巴矢量图标库 下面我们讲解在vue页面中引入阿里巴巴矢量图标库icon的几种方法 目录 一、引入在线链接 1、 第九步链接引入在vue中应该是在…

python小程序 图书馆图书借阅借还管理系统 mbc21

为设计一个安全便捷&#xff0c;并且使借阅者更好获取本图书借还信息&#xff0c;本文主要有安全、简洁为理念&#xff0c;实现借阅者快捷寻找图书借还信息&#xff0c;从而解决图书借还信息复杂难辨的问题。该系统以django架构技术为基础&#xff0c;采用python语言和MySQL数据…

科学数据分析和图形绘制软件GraphPad Prism 9 mac中文版特点介绍

Prism 9 mac是一款专业的科学数据分析和图形绘制软件&#xff0c;可用于在生物、医学、化学等领域进行数据分析、绘制图形、进行统计分析等。 Prism 9 mac软件特点 1. 多种数据分析功能&#xff1a;Prism 9提供了多种常见的数据分析工具&#xff0c;包括线性回归、ANOVA、t检验…

如何利用物联网技术打造新型智能餐饮连锁店

中国是美食大国&#xff0c;餐饮美食的消费需求庞大&#xff0c;随着餐饮产业的标准化、规模化发展&#xff0c;餐饮店的连锁化率在持续上升&#xff0c;许多餐饮知名品牌都开设了成百上千家连锁店。随着餐饮连锁店数量的增加&#xff0c;对品牌店铺的管理和运营难度也日益增长…

flowable可使用元素介绍

1. 事件 Events 事件描述图标空启动事件空启动事件未指定触发器&#xff0c;由用户调用的启动事件。定时启动事件定时启动事件在指定时间内创建一次或多次的流程实例。消息启动事件消息启动事件使用具名消息启动流程实例。消息名用于定位指定的启动事件。一个流程定义不得包含…

差值结构的顺序偏好

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点&#xff0c;AB训练集各由5张二值化的图片组成&#xff0c;让A 中有5个点&#xff0c;B中有1个点&#xff0c;且不重合&#xff0c;统计迭代次数并排序。 第一种情况 差值结构 迭代次数 L E - - 2 10491.…

Qt QCustomPlot介绍

介绍 主要介绍qcustomplot及其用法 最新版本:QCustomPlot Patch Release 2.1.1//November 6, 2022 下载:https://www.qcustomplot.com/index.php/download 官网:https://www.qcustomplot.com/index.php 简单使用 mainwindow.h /**************************************…