蓝桥杯— —小明的背包问题

小明的背包问题

小明的背包1 — — (01背包)

友情链接:小明的背包1

题目:

请添加图片描述

输入样例:

5 20
1 6
2 5
3 8
5 15
3 3 

输出样例:

37

思路:

对于01背包问题,其中一个重要的条件是每一种物品只有一个,因为在有n个物品v个容量的情况下的最大价值可以由它的子问题n - 1个物品v个容量的最大价值转化而来,因此我们可以利用动态规划的思想进行求解。

我们这样定义dp数组:我们令dp数组的第一维表示每一个物品,dp数组的第二维表示背包的容量。如题目给出的样例,(一共有5个物品,背包的容量为20)我们可以得到如下的dp数组:

01234567891011121314151617181920
0
1
2
3
4
5

对于第二维(即第一行数字)表示的是背包的容量,对于第一维(即第一列数字)表示的是物品的个数,背包的容量和物品的个数都是隐式存在的,并不是一个值,在程序中体现为下标(或索引)。

初始化dp数组:

对于背包容量为0的情况,我们能放入的物品的个数为0个,因此初始化dp数组的第一列的值为0。对于物品个数为0的情况,能放入背包的物品的个数也为0个,因此我们初始化dp数组的第一行的值为0

01234567891011121314151617181920
0000000000000000000000
10
20
30
40
50

递推公式:

对于每一行,即每一个物品来讲,如果当前的容量不能放入该物品,那么只能放入前面的物品,即当前容量能放入前面物品的最大价值,公式为:dp[i][j] = dp[i - 1][j],如果当前的容量能放入该物品,那么就尝试放入该物品,如果放入该物品后的价值更小,就不放入该物品,其值等于没有该物品的情况下当前背包的容量的最大价值,如果放入该物品后价值更大,就放入该物品。对应的公式为dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i] + v[i]]),对于公式dp[i - 1][j - w[i] + v[i]]的理解是,首先每一个物品都是1个,因此要从之前的物品开始减去当前物品的体积(相当于取出一些物品,腾出恰好的空间,得到在背包容量为j - w[i]的情况下的最大价值),然后再放入当前的物品,得到放入当前物品后的价值。公式max(dp[i - 1][j], dp[i - 1][j - w[i] + v[i]])的意义是:对于第i件物品,可以放或者不放,具体取值我哪一种情况的价值更大。

代码:

// 01背包问题
#include<iostream>
#include<vector>
using namespace std;

int solve(){
	int n,v;cin>>n>>v;   // 物品数量和背包容量
	vector<int> value(n + 1, 0);
	vector<int> weight(n + 1, 0); 
	for(int i = 1;i <= n;i ++){
		
		cin>>weight[i];
		cin>>value[i];
	}
	// 进行动态求解
	vector<vector<int>> dp(n + 1, vector<int>(v + 1, 0));
	dp[0][0] = 0;
	for(int i = 1;i <= n;i ++){
		dp[i][0] = 0;
	}
	for(int j = 1;j <= v;j ++){
		dp[0][j] = 0;
	}
	// 递推
	for(int i = 1;i <= n;i ++){  // 每一个物品 
		for(int j = 1;j <= v;j ++){  // 背包容量 
			if(j >= weight[i]){
				dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
			}else{
				dp[i][j] = dp[i - 1][j];   // 不用在和dp[i][j - 1]进行比较了,与完全背包原因一致 
			}
		}
	}
	cout<<dp[n][v]<<endl;
	return 0;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); 
	int t = 1;
	while(t--){
		solve();
	}
	return 0;
}

在这里插入图片描述

小明的背包2 — — (完全背包)

友情链接:小明的背包2

题目:

在这里插入图片描述

输入样例:

5 20
1 6
2 5
3 8
5 15
3 3 

输出样例:

120

思路:

多重背包问题01背包问题的区别在于,多重背包的每一种物品都可以有无限多个,因此我们只需要再递推公式上进行略微修改即可。

我们定义一个二维的dp数组,其含义与01背包定义的dp数组一样,第一维表示的是物品的种类,第二维表示的是背包的容量。

对于给出的输入样例,可以建立一下的dp数组。

01234567891011121314151617181920
0
1
2
3
4
5

定义边界:
背包容量为0和物品种类为0对应的价值都是0,因此我们要将背包容量为0的一列以及物品种类为0的一行初始化为0

01234567891011121314151617181920
0000000000000000000000
10
20
30
40
50

递推公式:

如果当前的容量不能放下该物品就继承自上一个物品再当前容量的dp值,对应的公式:dp[i][j] = dp[i - 1][j],可能有些小伙伴会有疑问,为什么不继承为max(dp[i - 1][j], dp[i][j - 1])呢?原因是:对于当前物品而言,如果不能放入,那么前一个容量自然也不能放入,依次类推到容量为0的情况,可以知道从0到当前情况每一个值都继承自当前容量的上一个物品的值,对于上一个物品而言,其值也是随着容量的增加而呈现出非严格单调递增的。所以使用公式:max(dp[i - 1][j], dp[i][j - 1])是没有意义的,当然最后的结果也是正确的,我们没有必要再进行一次额外的判断了。

如果当前的容量能够放下该物品,就对应两种动作:放或不放,如果放的话就在当前容量的基础上减去该物品的体积,然后加上该物品的价值,如果不放就取上一个物品对应当前容量的价值,公式为:dp[i][j] = max(dp[i - 1][j], dp[i][j - w[i]] + v[i]),这里与01背包不同的是dp[i][j - w[i]] + v[i]原因就在于完全背包问题可以对某一种物品放无限次,01背包只能对某一种物品放一次。

代码:

// 完全背包
#include<iostream>
#include<vector>
using namespace std;


int solve(){
	int n,v;cin>>n>>v;
	vector<int> value(n + 1, 0);
	vector<int> weight(n + 1, 0);
	for(int i = 1;i <= n;i ++){
		cin>>weight[i];
		cin>>value[i];
	}
	vector<vector<int>> dp(n + 1, vector<int>(v + 1, 0));
	for(int i = 1;i <= n;i ++){
		for(int j = 1;j <= v;j ++){
			if(j >= weight[i]){
				dp[i][j] = max(dp[i - 1][j], dp[i][j - weight[i]] + value[i]);
			}else{
				dp[i][j] = dp[i - 1][j];  // 不用在和 dp[i][j - 1] 进行比较了,因为如果放不下改为物品,那么之前的容量一定是取自上一个物品在当前容量的最大价值 
			}
		}
	}
	cout<<dp[n][v]<<endl;
	
	return 0;
}

int main(){
	ios::sync_with_stdio(0); 
	cin.tie(0);
	int t = 1;
	while(t--){
		solve();
	}
	return 0;
} 

在这里插入图片描述


持续更新中…

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题4

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题4 信息安全管理与评估 网络系统管理 网络搭建与应用 云计算 软件测试 移动应用开发 任务书&#xff0c;赛题&#xff0c;解析等资料&#xff0c;知识点培训服务 添加博主wx&#xff1a;liuliu548…

【Godot4.2】myPoint类 - 基于旋转和移动的点求取方式

概述 记得很久以前&#xff08;大约17年前&#xff09;有个用指令绘图的软件&#xff08;不是LOGO&#xff0c;而是它的一个模仿者&#xff0c;我找半天实在找不到。&#xff09;&#xff0c;基于移动和旋转来绘制折线。每次移动和旋转都是基于当前位置和方向&#xff0c;就像…

项目4-图书管理系统2+统一功能处理

1. 拦截器&#xff08;Interceptor&#xff09; 我们完成了强制登录的功能, 后端程序根据Session来判断用户是否登录, 但是实现⽅法是比较麻烦的。 所需要处理的内容&#xff1a; • 需要修改每个接⼝的处理逻辑 • 需要修改每个接⼝的返回结果 • 接⼝定义修改, 前端代码也需…

分享一个预测模型web APP的功能模块和界面的设计

一个临床预测模型web APP功能模块与界面设计 随着医疗技术的不断进步&#xff0c;web APP是临床预测模型在医学领域的应用的重要形式。这里分享一个web APP的设计&#xff0c;手里有医学预测模型的可以尝试将其构建成webAPP&#xff0c;进而在临床实践中体验预测模型带来的便利…

BugkuCTF:overflow2[WriteUP]

从题目中下载得到pwn文件 使用checksec工具对它进行检查&#xff0c;没有栈溢出保护 再根据题目提示可以知道这道题应该是利用栈溢出漏洞来做 把该文件放到linux中运行&#xff0c;可以看到有一个输入、输出的操作 把pwn丢进IDA里进行反编译分析 先看main函数&#xff0c;分…

Windows Server 2016虚拟机安装教程

一、VMware Workstation虚拟机软件的下载 官网下载入口&#xff1a;​​​​​​Download VMware Workstation Pro - VMware Customer Connect​​​​​ 下载好之后自己看着提示安装软件就好. 二、镜像文件的下载 下载网站入口&#xff1a;MSDN, 我告诉你 - 做一个安静…

关注招聘 关注招聘 关注招聘

&#x1f525;关注招聘 &#x1f525;关注招聘 &#x1f525;关注招聘 &#x1f525;开源产品&#xff1a; 1.农业物联网平台开源版 2.充电桩系统开源版 3.GPU池化软件(AI人工智能训练平台/推理平台) 开源版 产品销售&#xff1a; 1.农业物联网平台企业版 2.充电桩系统企业…

BCD BIN 转换

1&#xff0c;BCD是将10进制的每一位转换成2进制 如22 的中数子2的2进制就是0010&#xff0c;那么22的BCD 嘛就是 0010 0010 2&#xff0c;bin 的就是将2进制的每4位转成10进制 如 34的2进制就是0010 0010 高四位和低四位都是 0010 &#xff0c;0010对应的10进制就是2 那么…

FPGA压缩算法 (一)

压缩算法 简介 压缩算法是通过去除冗余信息来达到的&#xff0c;在图像压缩算法中一般是通过去除编码冗余、像素间冗余、心理视觉冗余这三者之间的一个或多个来完成的。 编码冗余&#xff1a;当所用码字大于最佳编码长度的时候出现的冗余 像素间冗余&#xff1a;因为图像数据间…

Redis:发布和订阅

文章目录 一、介绍二、发布订阅命令 一、介绍 Redis的发布和订阅功能是一种消息通信模式&#xff0c;发送者&#xff08;pub&#xff09;发送消息&#xff0c;订阅者&#xff08;sub&#xff09;接收消息。这种功能使得消息发送者和接收者不需要直接建立连接&#xff0c;而是通…

【vue】slot 匿名插槽 / 具名插槽

slot父组件向子组件传递数据 匿名插槽–直接写 具名插槽–指定名称 父组件中 子组件中&#xff1a; 代码 App.vue <template><h2>App.vue</h2><!-- 匿名插槽 --><Header><a href"1234567890.com">1234567890</a>&…

【Linux学习笔记】安卓设置内核信息的打印级别

开发环境 开发板&#xff1a;正点原子RK3568开发板安卓版本&#xff1a;11 问题描述 在串口调试过程中经常打印出这样的一些信息 极影响调试&#xff0c;暂时又没什么用&#xff0c;有些时候还不能给它直接关了。尤其是这个信息 healthd: battery l50 v3 t2.6 h2 st3 fc10…

Dubbo面试回答简单版

一、dubbo特性 超时重试机制地址缓存多版本负载均衡&#xff1a;随机、权重轮询、最少活跃调用、一致性哈希集群容错&#xff1a;失败重试、快速失败、失败安全、失败自动恢复、并行调用、广播服务降级&#xff1a;异常时返回mock 集群容错 FailOver 失败重试&#xff0c;读…

Matlab之空间坐标系绘制平面图形

在空间直角坐标系中&#xff0c;绘制指定平面方程的图形 版本说明&#xff1a; 20240413_V1.01&#xff1a;更正代码错误&#xff0c;并修改输入参数类型&#xff08;测试用例得修改&#xff09; 20240413_V1.00&#xff1a;初始版本 一、平面方程 基本形式为&#xff1a;A…

微服务边车模式深度解析:赋能云原生应用的终极指南(自己搞一个简单SideCar?)

什么是SideCar? Sidecar模式定义&#xff1a; Sidecar 模式是一种常用于微服务架构中的设计模式&#xff0c;该模式允许将应用程序的核心功能与辅助功能&#xff08;如日志记录、监控、配置管理、网络通信等&#xff09;分离开来。在这种设计模式中&#xff0c;每个微服务主容…

回归预测 | Matlab基于RIME-SVR霜冰算法优化支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于RIME-SVR霜冰算法优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于RIME-SVR霜冰算法优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab基于RIME-SVR霜冰算法优化支持向量机的数…

【数据结构】习题之消失的数字和轮转数组

&#x1f451;个人主页&#xff1a;啊Q闻 &#x1f387;收录专栏&#xff1a;《数据结构》 &#x1f389;前路漫漫亦灿灿 前言 消失的数字这道题目我会和大家分享三种思路。 还有一道题目是轮转数组&#xff0c;&#xff0c;也会分享三种思路&#xff0c;大…

照片和视频一键换脸,ROOP ROPE FaceFusion 中文版汉化版整合包下载安装

AI 人脸替换工具离线版下载地址&#xff1a;点击下载 AI 人脸替换工具离线版&#xff0c;将视频和图片的面孔替换为您选择的面孔。您只需要一张所需脸部的图像。没有数据集&#xff0c;就没有训练。工具包含 ROOP ROPE FaceFusion 三款人脸替换工具解压即用无需安装。 汉化整合…

【SpringBoot实战篇】注册接口

&#x1f495;&#x1f338;&#x1f340;开发接口的流程&#xff1a;明确需求 -》阅读接口文档-》思路分析-》开发-》测试&#x1f340;&#x1f338;&#x1f495; 开始前小知识-配置lombok&#x1f448;&#x1f340; lombok 在编译阶段,为实体类自动生成setter getter toSt…

教你将配置好的conda环境迁移到其它设备

文章目录 问题分析存在的方法环境要求方法步骤1. 下载conda pack2. 打包原环境3. 新设备还原环境4. 查看环境 问题分析 好不容易配置好的conda环境&#xff0c;要在另一个设备上运行&#xff0c;还要重新配置&#xff0c;好麻烦。 存在的方法 pip install -r requirement.txt …