3709: [PA2014]Bohater 贪心

傻傻的。

看到题目猜是贪心。结果只搞出了加血 > 减血的情况(很显然这种情况下把减血量从下到大排就可以了)。

下面讲一下 减血 > 加血的,顺便给出我的证明。

对于这种情况,网上许多题解都是说把加血从大到下排就可以了。然而蒟蒻我还是不大明白,所以简单证了一下。如果错了,请指正。

设当前血量为 z, 存在i, j 使得 a[i] > a[j] 

若先杀掉 j, 比先杀掉 i 优,(或者说存在先杀掉 j,后杀掉 i 能解决的情况而 先杀掉 i, 后杀掉 j 无法满足。)

那么 z - (d[i] - a[i]) <= d[j] (对应先杀掉 i 后杀 j 不能满足), z - (d[j] - a[j]) > d[i] (先杀掉 j,后杀掉 i 能解决)

很显然移项后得 z + a[i] <= d[j] + d[i],  z + a[j] > d[i] + d[j], 又因为 a[j] < a[i], 所以不成立。 所以不存在先杀掉 j,后杀掉 i 能解决的情况而 先杀掉 i, 后杀掉 j 无法满足的情况。

所以把加血从大到小排序后模拟一下吧! 

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<queue>
 5 #define rep(i,j,k) for(register int i = j; i <= k; i++)
 6 #define maxn 102333
 7 #define ll long long
 8 using namespace std;
 9 
10 inline int read() {
11     int s = 0, t = 1; char c = getchar();
12     while( !isdigit(c) ) { if( c == '-' ) t = -1; c = getchar(); }
13     while( isdigit(c) ) s = s * 10 + c - 48, c = getchar();
14     return s * t;
15 }
16 
17 struct node{ int d, a, t; } nod1[maxn], nod2[maxn];
18 bool cmp1(node a,node b) { return a.d < b.d; }
19 bool cmp2(node a,node b) { return a.a > b.a; }
20 int ans[maxn], top = 0;
21 int main() {
22     int n = read(); ll z = read();
23     int d, a, s1 = 0, s2 = 0;
24     rep(i,1,n) {
25         d = read(), a = read();
26         if( d > a ) {
27             nod2[++s2].d = d, nod2[s2].a = a, nod2[s2].t = i;
28         } else {
29             nod1[++s1].d = d, nod1[s1].a = a, nod1[s1].t = i;
30         } 
31     }
32     sort(nod1+1,nod1+1+s1,cmp1);
33     sort(nod2+1,nod2+1+s2,cmp2);
34     rep(i,1,s1) {
35         if( z > nod1[i].d ) {
36             ans[++top] = nod1[i].t;
37             z += nod1[i].a - nod1[i].d;
38         } else {
39             puts("NIE"); return 0;
40         }
41     }
42     rep(i,1,s2) {
43         if( z > nod2[i].d ) {
44             ans[++top] = nod2[i].t;
45             z += nod2[i].a - nod2[i].d;
46         } else {
47             puts("NIE"); return 0;
48         }
49     }
50     puts("TAK");
51     rep(i,1,n) if( i != n ) printf("%d ", ans[i]); else printf("%d\n", ans[i]);
52     return 0; 
53 }

 

人一我十,人十我万!追逐青春的梦想,怀着自信的心,永不放弃!仿佛已看到希望,尽管还在远方

posted on 2016-05-09 19:53  83131  阅读(163)  评论(0编辑  收藏  举报

导航