• BZOJ 3709: [PA2014]Bohater


    3709: [PA2014]Bohater

    Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special Judge
    Submit: 1050  Solved: 352
    [Submit][Status][Discuss]

    Description

    在一款电脑游戏中,你需要打败n只怪物(从1到n编号)。为了打败第i只怪物,你需要消耗d[i]点生命值,但怪物死后会掉落血药,使你恢复a[i]点生命值。任何时候你的生命值都不能降到0(或0以下)。请问是否存在一种打怪顺序,使得你可以打完这n只怪物而不死掉

    Input

    第一行两个整数n,z(1<=n,z<=100000),分别表示怪物的数量和你的初始生命值。
    接下来n行,每行两个整数d[i],a[i](0<=d[i],a[i]<=100000)

    Output

    第一行为TAK(是)或NIE(否),表示是否存在这样的顺序。
    如果第一行为TAK,则第二行为空格隔开的1~n的排列,表示合法的顺序。如果答案有很多,你可以输出其中任意一个。

    Sample Input

    3 5
    3 1
    4 8
    8 3

    Sample Output

    TAK
    2 3 1

    HINT

     

    Source

    [Submit][Status][Discuss]

    贪心,对于怪兽可以分成两类——

    一类,打完之后血量不降反升,这些怪兽按照消耗血量从小到大排序;

    一类,打完之后血量不升反降,这些怪兽按照恢复血量从大到小排序。

    且血量上升怪一定排在血量下降怪前面。

    易知这种打怪顺序是最优的,检测是否可行即可。

     1 #include <bits/stdc++.h>
     2 
     3 typedef long long longint;
     4 
     5 struct Monster {
     6     int a, b, id;
     7     Monster(void) {}
     8     Monster(int _a, int _b, int _id) {
     9         a = _a, b = _b, id = _id;
    10     }
    11 }
    12 mon1[200000],
    13 mon2[200000];
    14 
    15 bool cmp1(const Monster &a, const Monster &b) {
    16     return a.a < b.a;
    17 }
    18 
    19 bool cmp2(const Monster &a, const Monster &b) {
    20     return a.b > b.b;
    21 }
    22 
    23 int n; 
    24 longint h;
    25 int tot1, tot2;
    26 
    27 signed main(void) {
    28     scanf("%d%lld", &n, &h);
    29     
    30     for (int i = 1, a, b; i <= n; ++i) {
    31         scanf("%d%d", &a, &b);
    32         if (a < b)
    33             mon1[tot1++] = Monster(a, b, i);
    34         else
    35             mon2[tot2++] = Monster(a, b, i);
    36     }
    37     
    38     std::sort(mon1, mon1 + tot1, cmp1);
    39     std::sort(mon2, mon2 + tot2, cmp2);
    40     
    41     for (int i = 0; i < tot1; ++i) {
    42         if (h <= mon1[i].a)
    43             return puts("NIE"), 0;
    44         h -= mon1[i].a;
    45         h += mon1[i].b;
    46     }
    47     
    48     for (int i = 0; i < tot2; ++i) {
    49         if (h <= mon2[i].a)
    50             return puts("NIE"), 0;
    51         h -= mon2[i].a;
    52         h += mon2[i].b;
    53     }
    54     
    55     puts("TAK");
    56     
    57     for (int i = 0; i < tot1; ++i)
    58         printf("%d ", mon1[i].id);
    59     for (int i = 0; i < tot2; ++i)
    60         printf("%d ", mon2[i].id);
    61     
    62     return puts(""), 0;
    63 }

    @Auhtor: YouSiki

  • 相关阅读:
    不等式(一)-Markov与Chebyshev不等式
    决策树学习
    k-NN最近邻算法(k-nearest neighbors algorithm)
    梯度下降(Gradient Descent)数学原理分析与实例
    求解素数
    shell基础命令使用
    安装jenkins
    idea拉取git
    shell常用命令
    linux 安装jdk
  • 原文地址:https://www.cnblogs.com/yousiki/p/6142195.html
Copyright © 2020-2023  润新知