AtCoder Beginner Contest 085 D Katana Thrower(贪心)

Problem Statement

You are going out for a walk, when you suddenly encounter a monster. Fortunately, you have N katana (swords), Katana 1, Katana 2, …, Katana N, and can perform the following two kinds of attacks in any order:

Wield one of the katana you have. When you wield Katana i i (1in) ( 1 ≤ i ≤ n ) , the monster receives ai a i points of damage. The same katana can be wielded any number of times.

Throw one of the katana you have. When you throw Katana i i (1iN) ( 1 ≤ i ≤ N ) at the monster, it receives bi b i points of damage, and you lose the katana. That is, you can no longer wield or throw that katana.

The monster will vanish when the total damage it has received is H points or more. At least how many attacks do you need in order to vanish it in total?
Constraints

1 ≤ N≤ 10 5 5
1 ≤ H ≤ 10 9 9
1 ≤ a i i ≤ b i i ≤ 10 9 9
All input values are integers.

题意:你有N把剑,怪兽血量H,第i把剑能挥砍造成 ai a i 点伤害或投掷造成 bi b i 点伤害(投掷后不能再用),问最少攻击多少次把怪兽打死?
思路:把投掷伤害高的剑扔出去,用挥砍攻击最高的反复砍

#include
#include 
using namespace std;

int n, h;
#define maxn 100000
class sword {
public:
    //挥砍攻击力
    int a;
    //投掷攻击力
    int b;
    bool operator<(sword& as) {
        return b < as.b;
    }
}s[maxn+5];

int main() {
    int maxa = 0;
    int dmg=0;
    int att=0;

    cin>>n>>h;
    for (int i = 0; i < n; ++i) {
        cin>>s[i].a>>s[i].b;
    }

    //按投掷攻击力的大小排序(重载<运算符)
    sort(s, s + n);

    //找到挥砍攻击力最大的那把
    for (int i = 0; i < n; ++i) {
        maxa = s[maxa].a < s[i].a ? i : maxa;
    }
    //把投掷攻击力大于最大挥砍攻击力的剑从大到小依次扔出去
    for (int i = n - 1; dmg < h&&s[i].b> s[maxa].a;--i) {
        if (i == maxa)continue;//不能把最大挥砍攻击的剑扔了
        dmg += s[i].b; ++att;
    }

    //投掷攻击力更大的剑都扔出去了,剩下的伤害用最大挥砍攻击的剑完成
    //这里要注意,当砍到最后一下的时候,是可以把这把剑扔出去的
    if (dmg < h) {
        if (s[maxa].a > s[maxa].b) {
        //挥砍攻击力比投掷攻击力高,最后一下仍是挥砍攻击
            att +=  (h - dmg) / s[maxa].a;
            //向上取整
            if ((h - dmg) % s[maxa].a != 0) 
                ++att;

        }
        else {//挥砍攻击力比投掷攻击力低,最后一下可以投掷攻击
            //提前把投掷攻击的伤害算上
            att += 1; dmg += s[maxa].b;
            if (dmg < h) {
                att += (h - dmg) / s[maxa].a;
                //向上取整
                if ((h - dmg) % s[maxa].a != 0) 
                    ++att;
            }
        }
    }
    cout << att;
}

你可能感兴趣的:(acm)