我們首先將所有電池排序,那麼我們可以找到一組最優方案,使得一臺機器的能量之差是相鄰兩電池的能量之差。
然後我們就二分這個答案,從前往後貪心地選這個數對,然後看是否所有的數對都是滿足條件的。
假設這個數對是 i - 1, i,並且是第 j 個數對,那麼我們稱滿足條件為:
2nk - i + 2 >= 2k(n - j + 1)
意思就是能拿出足夠多的電池來組成機器人。
然後注意特判:如果不能選出足夠多的數對就返回 false,我在這裡 WA 到死。。。
畢竟 Gromah 太弱,只會做水題。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 1000000 + 5 int n, k, size, Max, A[N]; inline int getint()
{
char ch = '\n';
for (; ch > '' || ch < ''; ch = getchar()) ;
int res = ch - '';
for (ch = getchar(); ch >= '' && ch <= ''; ch = getchar())
res = (res << ) + (res << ) + ch - '';
return res;
} inline bool Judge(int m)
{
int cnt = n;
for (int i = ; cnt && i <= size; i ++)
if (A[i] - A[i - ] <= m)
{
if (size - i + < * cnt * k) return ;
cnt --, i ++;
}
return !cnt;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("3969.in", "r", stdin);
freopen("3969.out", "w", stdout);
#endif n = getint(), k = getint();
size = (n * k) << ;
for (int i = ; i <= size; i ++)
{
A[i] = getint();
Max = max(Max, A[i]);
}
sort(A + , A + size + );
int l = A[] - A[], r = Max;
while (l < r)
{
int mid = (l + r) >> ;
if (Judge(mid)) r = mid;
else l = mid + ;
}
printf("%d\n", l); #ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return ;
}