AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

AcWing 1022. 宠物小精灵之收服【二维费用01背包问题】    原题链接    简单

作者: 作者的头像   一只野生彩色铅笔 ,  2021-06-09 17:57:33 ,  所有人可见 ,  阅读 5669


62


11

最近在补全提高课所有题目的题解,宣传一下汇总的地方提高课题解补全计划

题目描述

傻东西 和 皮神 一起去抓 宝可梦

一共会遇到 $n$ 个 野生宝可梦,小智有 $m$ 个 精灵球,皮神有 $t$ 滴 血

对于每个 野生宝可梦 来说,如果要捕捉他,需要 $v_{1i}$ 个 精灵球,战斗后皮神要掉 $v_{2i}$ 滴 血

如果皮神 血量 $\le 0$,则小智停止狩猎

小智对于每个 野生宝可梦 要么收服,要么逃跑

求一种方案:收服 尽可能多 的 野生宝可梦 ;如果收服数量一样,要皮神 血量最多

输出该方案的 野生宝可梦 收服数量,以及皮神战斗结束后的 剩余血量

分析

y总在标签里很贴心的贴了一个 阅读理解 的tag,没错这就是一道阅读理解题

本题是一道 01背包 的扩展题 —— 二维费用01背包问题

把 野生宝可梦 看做物品,则捕捉他需要的 精灵球 个数就是第一费用,战斗皮神要掉的血就是第二费用

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

以上就是本题的 阅读理解分析部分 ,接下来直接上闫氏DP分析法

闫氏DP分析法

IMG_C0D309FBA487-1.jpeg

初始状态:f[0][0][0]
目标状态:f[n][m][t - 1] (皮神不能 再起不能 才算抓住那个 宝可梦 )

Code

时间复杂度:$O(n \times m \times k)$

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110, M = 1010, K = 510;

int n, m, t;
int v1[N], v2[N];
int f[M][K];

int main()
{
    //input
    cin >> m >> t >> n;
    for (int i = 1; i <= n; ++ i) cin >> v1[i] >> v2[i];

    //dp
    for (int i = 1; i <= n; ++ i)
    {
        for (int j = m; j >= v1[i]; -- j)
        {
            for (int k = t - 1; k >= v2[i]; -- k)
            {
                f[j][k] = max(f[j][k], f[j - v1[i]][k - v2[i]] + 1);
            }
        }
    }

    //output
    cout << f[m][t - 1] << " ";
    //找到满足最大价值的所有状态里,第二维费用消耗最少的
    int cost_health = t;
    for (int k = 0; k <= t - 1; ++ k)
    {
        if (f[m][k] == f[m][t - 1])
        {
            cost_health = min(cost_health, k);
        }
    }
    cout << t - cost_health << endl;
    return 0;
}

11 评论


用户头像
RwChen   2022-05-26 23:36      4    踩      回复
字真漂亮
用户头像
拔刀能挽留住樱吗   2023-05-22 20:29      1    踩      回复

漂亮滴很呐~(赞扬)


用户头像
一只会code的小金鱼   2022-07-11 10:05      1    踩      回复

很帅

用户头像
Cplusplus   2023-11-05 15:46         踩      回复

拿周赛牌了么


用户头像
Howardlhhhr   2023-07-22 13:32         踩      回复

#强!


用户头像
stifer   2022-08-27 10:18         踩      回复

为什么第一问输出结果为【m】【t - 1】

用户头像
stifer   2022-08-27 10:18         踩      回复

而不是t

用户头像
stifer   2022-08-27 10:31    回复了 stifer 的评论         踩      回复

最后找最小值的时候由于是由下往上找的可以找到直接输出即可

用户头像
stifer   2022-08-27 10:35    回复了 stifer 的评论      8    踩      回复

明白了,,,“而使得皮卡丘体力小于等于0的野生小精灵也不会被小智收服。”


用户头像
wngzs   2022-07-11 11:36         踩      回复

赞赞赞


用户头像
那慕灬鳳   2022-03-10 00:14         踩      回复

为什么第二问的循坏k要从0开始呢,从1开始答案就错了

用户头像
赖东东   2022-03-13 22:35      6    踩      回复

因为有可能一只宠物都捕捉不了,这时候的体力消耗是为0的,如果最小从1开始枚举得到的最小值是1,那无论如何求出来的最小值都为1了。


App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息