Bzoj3709 [PA2014]Bohater

传送门: http://www.lydsy.com/JudgeOnline/problem.php?id=3709
题意: 在一款电脑游戏中,你需要打败 n 只怪物(从 1 n 编号)。为了打败第 i 只怪物,你需要消耗 di 点生命值,但怪物死后会掉落血药,使你恢复 ai 点生命值。任何时候你的生命值都不能降到 0 (或 0 以下)。请问是否存在一种打怪顺序,使得你可以打完这 n 只怪物而不死掉。(1n105)
题解: 贪心地想,如果一个怪物 d<a ,那么这种怪物肯定是优先打的,可以补血,其次是 d=a 这种怪打了和没打一样,最后再打 d>a 的,因为会掉血。同样是 d<a d 小的优先打,因为如果连 d 小的都打不下来肯定打不了大的,而且打完后血量肯定变多;同样是 d=a 的优先顺序无所谓;同样是 d>a a 大的优先打,因为打完所有怪最后一个怪的 a 是浪费的,这种浪费更小就越有可能打完所有怪物。

#include<bits/stdc++.h>
const int N = 1e5 + 10;
template <typename T> void read(T &x) {
    x = 0; char c = getchar();
    for (; !isdigit(c); c = getchar());
    for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
}
struct rec{int d, i, det, num;} a[N];
bool cmp(const rec &a, const rec &b) {
    if (a.det > 0) return b.det > 0 ? a.d < b.d : 1;
    if (a.det < 0) return b.det < 0 ? a.i > b.i : 0;
    if (b.det == 0) return a.d > b.d;
    return b.det < 0;
}
int n;
long long z;
bool suc = 1;
int main() {
    read(n); read(z);
    for (int i = 1; i <= n; i++)
        read(a[i].d), read(a[i].i),
        a[i].det = a[i].i - a[i].d, a[i].num = i;
    std::sort(a + 1, a + n + 1, cmp);
    for (int i = 1; suc && i <= n; i++)
        suc &= (z -= a[i].d) > 0,
        z += a[i].i;
    if (!suc) {printf("NIE\n"); return 0;}
    printf("TAK\n");
    for (int i = 1; i < n; i++)
        printf("%d ", a[i].num);
    printf("%d\n", a[n].num);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值