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; }