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 }
View Code

 

posted @ 2018-11-23 22:08  Dup4  阅读(153)  评论(0编辑  收藏  举报