首页 > 代码库 > bzoj3709 [PA2014]Bohater

bzoj3709 [PA2014]Bohater

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3709

【题解】

打完怪最后的体力是固定的,设为lst

我们考虑回血量>=扣血量的怪,这些肯定优先打,顺序肯定是按照扣血量从小到大打,这一定是最优策略,打不了就是NIE了

接着由于lst固定,我们考虑扣血量>回血量的怪,就相当于从lst开始

每次打一个怪吐出“回血量”这么多的血,增加“扣血量”这么多的血。

于是从后往前,就是按回血量从小到大打,依次判断即可。

技术分享
# include <set>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int M = 5e5 + 10;
const int mod = 1e9+7;

# define RG register
# define ST static

int n;
ll cur, lst;
struct pa {
    int d, a, id;
    pa() {}
    pa(int d, int a, int id) : d(d), a(a), id(id) {}
}p[M], q[M];
int pn = 0, qn = 0;

inline bool cmp(pa a, pa b) {
    return a.d < b.d;
}
inline bool cmp2(pa a, pa b) {
    return a.a < b.a;
}

int main() {
    cin >> n >> cur; lst = cur;
    for (int i=1, D, A, C; i<=n; ++i) {
        scanf("%d%d", &D, &A);
        C = A-D;
        lst += C;
        if(C >= 0) p[++pn] = pa(D, A, i);
        else q[++qn] = pa(D, A, i);
    }
    sort(p+1, p+pn+1, cmp);
    sort(q+1, q+qn+1, cmp2);
    for (int i=1; i<=pn; ++i) 
        if(cur <= p[i].d) {
            puts("NIE");
            return 0;
        } else cur = cur - p[i].d + p[i].a;
    for (int i=1; i<=qn; ++i) 
        if(lst <= q[i].a) {
            puts("NIE");
            return 0;
        } else lst = lst - q[i].a + q[i].d;
    puts("TAK");
    for (int i=1; i<=pn; ++i) printf("%d ", p[i].id);
    for (int i=qn; i; --i) printf("%d ", q[i].id);
    return 0;
}
View Code

 

bzoj3709 [PA2014]Bohater