標籤:
我們首先將所有電池排序,那麼我們可以找到一組最優方案,使得一台機器的能量之差是相鄰兩電池的能量之差。
然後我們就二分這個答案,從前往後貪心地選這個數對,然後看是否所有的數對都是滿足條件的。
假設這個數對是 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 = ‘\n‘;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_JUDGE36 freopen("3969.in", "r", stdin);37 freopen("3969.out", "w", stdout);38 #endif39 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\n", l);56 57 #ifndef ONLINE_JUDGE58 fclose(stdin);59 fclose(stdout);60 #endif61 return 0;62 }
BZOJ 3969 Low Power 解題報告