AcWing 1022" role="presentation">1022. 宠物小精灵之收服 一、题目描述 宠物小精灵是一部讲述小智和他的搭档皮卡丘一起冒险的故事。 一天,小智和皮卡丘来到了小精灵狩猎场,里面有很多珍贵的野生宠物小精灵。 小智也想收服其中的一些小精灵。 然而,野生的小精灵并不那么容易被收服。 对于每一个野生小精灵而言,小智可" />
首页 > 分享 > AcWing 1022. 宠物小精灵之收服

AcWing 1022. 宠物小精灵之收服

AcWing" role="presentation">AcWing 1022" role="presentation">1022. 宠物小精灵之收服

一、题目描述

宠物小精灵是一部讲述小智和他的搭档皮卡丘一起冒险的故事。

一天,小智和皮卡丘来到了小精灵狩猎场,里面有很多珍贵的野生宠物小精灵。

小智也想收服其中的一些小精灵。

然而,野生的小精灵并不那么容易被收服。

对于每一个野生小精灵而言,小智可能需要使用很多个精灵球才能收服它,而在收服过程中,野生小精灵也会对皮卡丘造成一定的伤害(从而减少皮卡丘的体力)。

当皮卡丘的体力小于等于0" role="presentation">0时,小智就必须结束狩猎(因为他需要给皮卡丘疗伤),而 使得皮卡丘体力小于等于0" role="presentation">0的野生小精灵也不会被小智收服

当小智的精灵球用完时,狩猎也宣告结束。

我们假设小智遇到野生小精灵时有两个选择:收服它,或者离开它。

如果小智选择了收服,那么一定会扔出能够收服该小精灵的精灵球,而皮卡丘也一定会受到相应的伤害;如果选择离开它,那么小智不会损失精灵球,皮卡丘也不会损失体力。

小智的目标有两个:主要目标是收服尽可能多的野生小精灵;如果可以收服的小精灵数量一样,小智希望皮卡丘受到的伤害越小(剩余体力越大),因为他们还要继续冒险。

现在已知小智的精灵球数量和皮卡丘的初始体力,已知每一个小精灵需要的用于收服的精灵球数目和它在被收服过程中会对皮卡丘造成的伤害数目。

请问,小智该如何选择收服哪些小精灵以达到他的目标呢?

输入格式
输入数据的第一行包含三个整数:N,M,K" role="presentation">N,M,K,分别代表小智的精灵球数量、皮卡丘初始的体力值、野生小精灵的数量。

之后的K" role="presentation">K行,每一行代表一个野生小精灵,包括两个整数:收服该小精灵需要的精灵球的数量,以及收服过程中对皮卡丘造成的伤害。

输出格式
输出为一行,包含两个整数:C,R" role="presentation">C,R,分别表示最多收服C" role="presentation">C个小精灵,以及收服C" role="presentation">C个小精灵时皮卡丘的剩余体力值最多为R" role="presentation">R。

数据范围
0&lt;N&#x2264;1000,0&lt;M&#x2264;500,0&lt;K&#x2264;100" role="presentation">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

二、题目解析

分析

本题是一道 01背包 的扩展题 —— 二维费用01" role="presentation">01背包问题

野生的小精灵 看做物品,则捕捉他需要的 精灵球 个数就是第一费用,皮卡丘要掉的血就是 第二费用

最后答案要求 物品数量 最多,因此我们可以用 状态的属性 来表示 选择的物品数

闫氏DP分析法

初始状态:f[0][0][0]
目标状态:f[n][m][t - 1] (皮神不能的血不能全部流光,否则它就挂了~)

三、实现代码

时间复杂度:O(n&#xD7;m&#xD7;k)" role="presentation">O(n×m×k)

#include <bits/stdc++.h> using namespace std; const int N = 110; // 野生小精灵的数量 const int M1 = 1010; // 小智的精灵球数量 const int M2 = 510; // 皮卡丘的体力值 int n, m1, m2; int f[M1][M2]; // 一维:精灵球数量,二维:皮卡丘的体力值,值:抓到的小精灵数量最大值 int main() { cin >> m1 >> m2 >> n; m2--; // 留一滴血 // 二维费用01背包 // 降维需要将体积1、体积2倒序枚举 for (int i = 1; i <= n; i++) { int v1, v2; cin >> v1 >> v2; for (int j = m1; j >= v1; j--) for (int k = m2; k >= v2; k--) f[j][k] = max(f[j][k], f[j - v1][k - v2] + 1); // 获利就是多了一个小精灵 } // 最多收服多少个小精灵[在消耗精灵球、血极限的情况下,肯定抓的是最多的,这不废话吗] printf("%d ", f[m1][m2]); // 找到满足最大价值的所有状态里,第二维费用消耗最少的 int cost = m2; for (int i = 0; i <= m2; i++) // 如果一个都不收服,则体力消耗最少,消耗值为0 if (f[m1][i] == f[m1][m2]) cost = min(cost, i); // 收服最多个小精灵时皮卡丘的剩余体力值最大是多少 printf("%dn", m2 + 1 - cost); return 0; }

四、二维费用01" role="presentation">01背包练习题

AcWing 8. 二维费用的背包问题

实现代码

#include <bits/stdc++.h> using namespace std; int f[1010][1010]; /* 测试数据: 4 5 6 1 2 3 2 4 4 3 4 5 4 5 6 答案: 8 */ int n, V, M; int main() { scanf("%d %d %d", &n, &V, &M); //物品件数背包容量背包承重 for (int i = 1; i <= n; i++) { //枚举物品 int v, m, w; //体积重量 价值 scanf("%d %d %d", &v, &m, &w); for (int j = V; j >= v; j--) //枚举体积 for (int k = M; k >= m; k--) //枚举承重 f[j][k] = max(f[j][k], f[j - v][k - m] + w); } printf("%dn", f[V][M]); return 0; } AcWing" role="presentation">AcWing 1022" role="presentation">1022. 宠物小精灵之收服    一、题目描述    二、题目解析    三、实现代码    四、二维费用01" role="presentation">01背包练习题        实现代码

__EOF__

本文作者: 蒟蒻豆进阶之路 本文链接: https://www.cnblogs.com/littlehb/p/15666368.html 关于博主: 评论和私信会在第一时间回复。或者直接私信我。 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处! 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。

相关知识

AcWing 1022 宠物小精灵之收服
宠物小精灵之收服
Bailian4102 宠物小精灵之收服【模拟】
宠物小精灵之收服(二维背包)
1292:宠物小精灵之收服
【openjudge】宠物小精灵之收服
【动态规划】宠物小精灵之收服
C++解决:宠物小精灵之收服【oj】
洛谷 U266184 宠物小精灵之收服
Acwing.提高课.宠物小精灵之收服(c++题解)

网址: AcWing 1022. 宠物小精灵之收服 https://m.mcbbbk.com/newsview733397.html

所属分类:萌宠日常
上一篇: 口袋精灵2宠物神殿专属任务详细攻
下一篇: 宠物小精灵日月攻略宠物小精灵日月