算法学习系列(五十一):背包模型(一)

2024-04-24 20:12

本文主要是介绍算法学习系列(五十一):背包模型(一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 引言
  • 一、采药
  • 二、装箱问题
  • 三、宠物小精灵之收服

引言

关于 背包问题 可以参考我之前的博客,由于基础的算法和模板已经学过了,所以现在就是开始学模型了,难点就是阅读理解、抽象模型、代码熟练度、心理素质也就是这几个难点了,其实就是多练就好了,加油!


一、采药

标签:DP、01背包问题

思路:就是一道很裸的 01 01 01 背包问题,我们把时间看作背包的容积,数量看作物品的个数,并且每件物品只能选一次,所以直接拿模板去解就行了。这里的写法跟之前的不太一样,我们发现每次的 w [ i ] , v [ i ] w[i],v[i] w[i],v[i] 其实就是该次的,不用存直接在输入的时候就一读,之后也就不用了,所以可以用如下的写法。

题目描述:

辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它
自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的
总价值最大。”如果你是辰辰,你能完成这个任务吗?输入格式
输入文件的第一行有两个整数 T 和 M,用一个空格隔开,T 代表总共能够用来采药的时间,M 代表山洞里的草药的数目。接下来的 M 行每行包括两个在 1 到 100 之间(包括 1 和 100)的整数,分别表示采摘某株草药的时间和这株草药的价值。输出格式
输出文件包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。数据范围
1≤T≤1000,1≤M≤100
输入样例:
70 3
71 100
69 1
1 2
输出样例:
3

示例代码:

#include <bits/stdc++.h>using namespace std;typedef long long LL;
typedef pair<int,int> PII;
#define x first
#define y secondconst int N = 110, M = 1010;int n, m;
int f[M];int main()
{ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> m >> n;for(int i = 1; i <= n; ++i){int v, w; cin >> v >> w;for(int j = m; j >= v; --j){f[j] = max(f[j], f[j-v]+w);}}cout << f[m] << endl;return 0;
}

二、装箱问题

标签:DP、01背包问题

思路:这个背包问题其实就是一个组合问题,问在满足条件的情况下,什么样的组合能使得某个值最大。这道题首先每个物品只能选择一次,所以判断是 01 01 01 背包,然后容量就是题意,问的是剩余空间最小,也就是装入的体积最大,也就是将体积看作价值了,求价值最大,也就是模板了,跟上一题一样。

题目描述:

有一个箱子容量为 V,同时有 n 个物品,每个物品有一个体积(正整数)。要求 n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。输入格式
第一行是一个整数 V,表示箱子容量。第二行是一个整数 n,表示物品数。接下来 n 行,每行一个正整数(不超过10000),分别表示这 n 个物品的各自体积。输出格式
一个整数,表示箱子剩余空间。数据范围
0<V≤20000,0<n≤30
输入样例:
24
6
8
3
12
7
9
7
输出样例:
0

示例代码:

#include <bits/stdc++.h>using namespace std;typedef long long LL;
typedef pair<int,int> PII;
#define x first
#define y secondconst int N = 2e4+10;int n, m;
int f[N];int main()
{ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> m >> n;for(int i = 1; i <= n; ++i){int v; cin >> v;for(int j = m; j >= v; --j){f[j] = max(f[j], f[j-v]+v);}}cout << m - f[m] << endl;return 0;
}

三、宠物小精灵之收服

标签:DP、01背包问题、阅读理解

思路:这道题相当于是有两个体积,然后剩余的就跟模板一样,然后注意这里的体积二不能被取满,因为取满所包含的那个数不算,当然也有可能算这个体积最后的值也没有变化,所以这里直接取 f [ V 1 ] [ V 2 − 1 ] f[V1][V2-1] f[V1][V21] 即可。然后第二问求的是最优解的情况下体积二最小是多少,那直接拿循环判断即可,详情见代码。

题目描述:

宠物小精灵是一部讲述小智和他的搭档皮卡丘一起冒险的故事。一天,小智和皮卡丘来到了小精灵狩猎场,里面有很多珍贵的野生宠物小精灵。小智也想收服其中的一些小精灵。然而,野生的小精灵并不那么容易被收服。对于每一个野生小精灵而言,小智可能需要使用很多个精灵球才能收服它,而在收服过程中,野生小精灵也会对皮卡丘造成一定
的伤害(从而减少皮卡丘的体力)。当皮卡丘的体力小于等于0时,小智就必须结束狩猎(因为他需要给皮卡丘疗伤),而使得皮卡丘体力小于等于0的野生小精灵也
不会被小智收服。当小智的精灵球用完时,狩猎也宣告结束。我们假设小智遇到野生小精灵时有两个选择:收服它,或者离开它。如果小智选择了收服,那么一定会扔出能够收服该小精灵的精灵球,而皮卡丘也一定会受到相应的伤害;如果选择离开它,那么
小智不会损失精灵球,皮卡丘也不会损失体力。小智的目标有两个:主要目标是收服尽可能多的野生小精灵;如果可以收服的小精灵数量一样,小智希望皮卡丘受到的伤害越小
(剩余体力越大),因为他们还要继续冒险。现在已知小智的精灵球数量和皮卡丘的初始体力,已知每一个小精灵需要的用于收服的精灵球数目和它在被收服过程中会对皮卡
丘造成的伤害数目。请问,小智该如何选择收服哪些小精灵以达到他的目标呢?输入格式
输入数据的第一行包含三个整数:N,M,K,分别代表小智的精灵球数量、皮卡丘初始的体力值、野生小精灵的数量。之后的K行,每一行代表一个野生小精灵,包括两个整数:收服该小精灵需要的精灵球的数量,以及收服过程中对皮卡丘造成的
伤害。输出格式
输出为一行,包含两个整数:C,R,分别表示最多收服C个小精灵,以及收服C个小精灵时皮卡丘的剩余体力值最多为R。数据范围
0<N≤1000,0<M≤500,0<K≤100
输入样例1:
10 100 5
7 10
2 40
2 50
1 20
4 20
输出样例1:
3 30
输入样例2:
10 100 5
8 110
12 10
20 10
5 200
1 110
输出样例2:
0 100

示例代码:

#include <bits/stdc++.h>using namespace std;typedef long long LL;
typedef pair<int,int> PII;
#define x first
#define y secondconst int N = 1010, M = 510;int V1, V2, n;
int f[N][M];int main()
{ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);cin >> V1 >> V2 >> n;for(int i = 1; i <= n; ++i){int v1, v2; cin >> v1 >> v2;for(int j = V1; j >= v1; --j){for(int k = V2; k >= v2; --k){f[j][k] = max(f[j][k], f[j-v1][k-v2]+1);}}}int res = f[V1][V2-1];cout << res << " ";int k = V2 - 1;while(k >= 0 && f[V1][k] == res) k--;cout << V2 - k - 1 << endl;return 0;
}

这篇关于算法学习系列(五十一):背包模型(一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/932724

相关文章

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

详解如何使用Python从零开始构建文本统计模型

《详解如何使用Python从零开始构建文本统计模型》在自然语言处理领域,词汇表构建是文本预处理的关键环节,本文通过Python代码实践,演示如何从原始文本中提取多尺度特征,并通过动态调整机制构建更精确... 目录一、项目背景与核心思想二、核心代码解析1. 数据加载与预处理2. 多尺度字符统计3. 统计结果可

SpringBoot整合Sa-Token实现RBAC权限模型的过程解析

《SpringBoot整合Sa-Token实现RBAC权限模型的过程解析》:本文主要介绍SpringBoot整合Sa-Token实现RBAC权限模型的过程解析,本文给大家介绍的非常详细,对大家的学... 目录前言一、基础概念1.1 RBAC模型核心概念1.2 Sa-Token核心功能1.3 环境准备二、表结

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各