• BZOJ 3709 [PA2014]Bohater:贪心【反过来考虑】


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3709

    题意:

      在一款电脑游戏中,你需要打败n只怪物(从1到n编号)。

      为了打败第i只怪物,你需要消耗atk[i]点生命值,但怪物死后会掉落血药,使你恢复rec[i]点生命值。

      任何时候你的生命值都不能降到0(或0以下)。

      请问是否存在一种打怪顺序,使得你可以打完这n只怪物而不死掉。

    题解:

      怪物总共分两种,一种是打完能回血的,一种是打完会掉血的。

      显然,先打能回血的,再打能掉血的。

      分别考虑两种怪:

        (1)能回血的:

          显然,先打atk小的怪物。按atk升序排列。

        (2)会掉血的:

          最后打完所有怪之后的血量end是一定的。

          那么将这个过程反过来考虑:初始血量为end,每打一个怪物掉rec[i]的血,然后回atk[i]的血。

          所以按照rec降序排列。

      最后模拟一遍能不能打完就行了。

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define MAX_N 100005
     6 
     7 using namespace std;
     8 
     9 struct Mons
    10 {
    11     int atk;
    12     int rec;
    13     int idx;
    14     Mons(int _atk,int _rec,int _idx)
    15     {
    16         atk=_atk;
    17         rec=_rec;
    18         idx=_idx;
    19     }
    20     Mons(){}
    21     friend bool operator < (const Mons &a,const Mons &b)
    22     {
    23         if(a.rec-a.atk>=0 && b.rec-b.atk>=0) return a.atk<b.atk;
    24         else if(a.rec-a.atk<0 && b.rec-b.atk<0)return a.rec>b.rec;
    25         return a.rec-a.atk>b.rec-b.atk;
    26     }
    27 };
    28 
    29 int n;
    30 long long hp;
    31 bool failed=false;
    32 Mons mons[MAX_N];
    33 
    34 void read()
    35 {
    36     cin>>n>>hp;
    37     for(int i=1;i<=n;i++)
    38     {
    39         cin>>mons[i].atk>>mons[i].rec;
    40         mons[i].idx=i;
    41     }
    42 }
    43 
    44 void solve()
    45 {
    46     sort(mons+1,mons+n+1);
    47     for(int i=1;i<=n;i++)
    48     {
    49         hp-=mons[i].atk;
    50         if(hp<=0)
    51         {
    52             failed=true;
    53             break;
    54         }
    55         hp+=mons[i].rec;
    56     }
    57 }
    58 
    59 void print()
    60 {
    61     if(failed)
    62     {
    63         cout<<"NIE"<<endl;
    64         return;
    65     }
    66     cout<<"TAK"<<endl;
    67     for(int i=1;i<=n;i++)
    68     {
    69         cout<<mons[i].idx<<" ";
    70     }
    71     cout<<endl;
    72 }
    73 
    74 int main()
    75 {
    76     read();
    77     solve();
    78     print();
    79 }
  • 相关阅读:
    安装的时候,突然安装程序关闭,的灵异问题。
    CSAPP阅读笔记(1)-序
    CSAPP阅读笔记(2)-虚存管理
    nafxcwd.lib(afxmem.obj) :error LNK2005:"void * __cdecl operator new(unsigned int)"
    Linux内核源代码情景分析读书笔记(5)-关于fork/clone/vfork
    [转]调试经验总结VC下的错误对话框
    IP数据包首部的校验和算法
    Matlab画图及生成exe文件
    VC++6.0中的new
    Linux内核模块编译、加载&卸载及查看运行结果
  • 原文地址:https://www.cnblogs.com/Leohh/p/7647999.html
Copyright © 2020-2023  润新知