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

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的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1