zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    1062 Talent and Virtue (25 分)
    1083 List Grades (25 分)
    1149 Dangerous Goods Packaging (25 分)
    1121 Damn Single (25 分)
    1120 Friend Numbers (20 分)
    1084 Broken Keyboard (20 分)
    1092 To Buy or Not to Buy (20 分)
    数组与链表
    二叉树
    时间复杂度与空间复杂度
  • 原文地址:https://www.cnblogs.com/Leohh/p/7647999.html
Copyright © 2011-2022 走看看