贪心水题= =
如果可以的话,我们发现最后答案是确定的,故只要将序列分为两部分:
(1)杀完能回血的按照消耗升序
(2)剩余按血药回血量降序
然后模拟一遍判断是否合法即可
1 /************************************************************** 2 Problem: 3709 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:728 ms 7 Memory:3152 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 13 using namespace std; 14 typedef long long ll; 15 const int N = 100005; 16 17 int n, t1, t2; 18 ll z; 19 20 struct data { 21 int d, a, w; 22 data() {} 23 data(int _d, int _a, int _w) : d(_d), a(_a), w(_w) {} 24 }a[N], b[N]; 25 inline bool cmp_a(const data &a, const data &b) { 26 return a.d < b.d; 27 } 28 inline bool cmp_b(const data &a, const data &b) { 29 return a.a > b.a; 30 } 31 32 inline int read() { 33 int x = 0; 34 char ch = getchar(); 35 while (ch < '0' || '9' < ch) 36 ch = getchar(); 37 while ('0' <= ch && ch <= '9') { 38 x = x * 10 + ch - '0'; 39 ch = getchar(); 40 } 41 return x; 42 } 43 44 int len = 0, pr[15]; 45 inline void print(int x) { 46 if (x == 0) { 47 putchar('0'), putchar(' '); 48 return; 49 } 50 while (x) 51 pr[++len] = x % 10, x /= 10; 52 while (len) 53 putchar(pr[len--] + '0'); 54 putchar(' '); 55 } 56 57 int main() { 58 int i, x, y; 59 n = read(), z = read(); 60 for (i = 1; i <= n; ++i) { 61 x = read(), y = read(); 62 if (x <= y) a[++t1] = data(x, y, i); 63 else b[++t2] = data(x, y, i); 64 } 65 sort(a + 1, a + t1 + 1, cmp_a); 66 for (i = 1; i <= t1; ++i) 67 if (z <= a[i].d) { 68 puts("NIE"); 69 return 0; 70 } else 71 z -= a[i].d - a[i].a; 72 sort(b + 1, b + t2 + 1, cmp_b); 73 for (i = 1; i <= t2; ++i) 74 if (z <= b[i].d) { 75 puts("NIE"); 76 return 0; 77 } else 78 z -= b[i].d - b[i].a; 79 puts("TAK"); 80 for (i = 1; i <= t1; ++i) 81 print(a[i].w); 82 for (i = 1; i <= t2; ++i) 83 print(b[i].w); 84 puts(""); 85 return 0; 86 }
(p.s. Rank 5,话说Rank 2一看就知道是二逼读入优化的23333)