BZOJ 3709: [PA2014]Bohater
考虑将怪物分为两种,一种是$回血>= 扣血,另一种是回血 < 扣血$
显然 第一种要在第二种前面打, 因为每次打完怪兽后,我们都可以加血,那么我们要先打扣血小的,因为如果扣血小的都打不了,那么扣血大的肯定打不了。
对于第二种怪兽,要先打加血多的,因为我们知道假如所有怪兽可以打完,那么最后的血量是一样的,如果把加血多的留在最后留在,那么相当于这部分血是没有贡献的。
也可以考虑,如果对于一个怪兽,此时如果打不死,那么之后肯定是不会打死的,因为在打第二类怪兽的过程是一个掉血的过程,何不如把加血多的放前面
也可以提供一组简单的样例
2 6
5 4
6 1
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 #define N 100010 6 int n; ll z; 7 struct node 8 { 9 int a, d, id, vis; 10 node () {} 11 node (int a, int d, int id, int vis) : a(a), d(d), id(id), vis(vis) {} 12 bool operator < (const node &r) const 13 { 14 if (vis == r.vis) 15 return (vis ? d < r.d : a > r.a); 16 else 17 return vis > r.vis; 18 } 19 }arr[N]; 20 21 bool ok() 22 { 23 for (int i = 1; i <= n; ++i) 24 { 25 z -= arr[i].d; 26 if (z <= 0) return false; 27 z += arr[i].a; 28 } 29 return true; 30 } 31 32 int main() 33 { 34 while (scanf("%d%lld", &n, &z) != EOF) 35 { 36 for (int i = 1, a, d; i <= n; ++i) 37 { 38 scanf("%d%d", &d, &a); 39 arr[i] = node(a, d, i, a >= d); 40 } 41 sort(arr + 1, arr + 1 + n); 42 if (ok()) 43 { 44 puts("TAK"); 45 for (int i = 1; i <= n; ++i) printf("%d%c", arr[i].id, " \n"[i == n]); 46 } 47 else 48 puts("NIE"); 49 } 50 return 0; 51 }