BZOJ 3969 Low Power 解题报告

我们首先将所有电池排序,那么我们可以找到一组最优方案,使得一台机器的能量之差是相邻两电池的能量之差。

然后我们就二分这个答案,从前往后贪心地选这个数对,然后看是否所有的数对都是满足条件的。

假设这个数对是 i - 1, i,并且是第 j 个数对,那么我们称满足条件为:

2nk - i + 2 >= 2k(n - j + 1)

意思就是能拿出足够多的电池来组成机器人。

然后注意特判:如果不能选出足够多的数对就返回 false,我在这里 WA 到死。。。

毕竟 Gromah 太弱,只会做水题。

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 #define N 1000000 + 5
 8   
 9 int n, k, size, Max, A[N];
10   
11 inline int getint()
12 {
13     char ch = '
';
14     for (; ch > '9' || ch < '0'; ch = getchar()) ;
15     int res = ch - '0';
16     for (ch = getchar(); ch >= '0' && ch <= '9'; ch = getchar())
17         res = (res << 3) + (res << 1) + ch - '0';
18     return res;
19 }
20   
21 inline bool Judge(int m)
22 {
23     int cnt = n;
24     for (int i = 2; cnt && i <= size; i ++)
25         if (A[i] - A[i - 1] <= m)
26         {
27             if (size - i + 2 < 2 * cnt * k) return 0;
28             cnt --, i ++;
29         }
30     return !cnt;
31 }
32   
33 int main()
34 {
35     #ifndef ONLINE_JUDGE
36         freopen("3969.in", "r", stdin);
37         freopen("3969.out", "w", stdout);
38     #endif
39       
40     n = getint(), k = getint();
41     size = (n * k) << 1;
42     for (int i = 1; i <= size; i ++)
43     {
44         A[i] = getint();
45         Max = max(Max, A[i]);
46     }
47     sort(A + 1, A + size + 1);
48     int l = A[2] - A[1], r = Max;
49     while (l < r)
50     {
51         int mid = (l + r) >> 1;
52         if (Judge(mid)) r = mid;
53             else l = mid + 1;
54     }
55     printf("%d
", l);
56       
57     #ifndef ONLINE_JUDGE
58         fclose(stdin);
59         fclose(stdout);
60     #endif
61     return 0;
62 }
原文地址:https://www.cnblogs.com/gromah/p/4424005.html