public static int maxTaskAssign(int[] aArray, int[] bArray, int p, int e) {
Arrays.sort(aArray); // A队成员从小到大排序
Arrays.sort(bArray); // B队成员从小到大排序
// 二分查找:可歼灭的A队的最大区间
int left = 0;
int right = Math.min(aArray.length, bArray.length);
while (left < right) {
int mid = left + (right - left + 1) / 2;
if (check(aArray, bArray, p, e, mid)) {
// 前面区间已确认可歼灭,往后面探索最优边界值
left = mid;
} else {
// 该区间不可歼灭,缩小区间范围
right = mid - 1;
}
}
return left;
}
private static boolean check(int[] aArray, int[] bArray, int p, int e, int k) {
LinkedList<Integer> bList = new LinkedList<>();
int idx = bArray.length - 1;
for (int i=k-1; i>=0; i--) {
int t = aArray[i];
// topK:至少保证"加上能量值"后是可战胜的
while (idx>=0 && bArray[idx]+e > t) {
bList.offer(bArray[idx]); // B队topK成员优先队列
idx--;
}
// 无可战胜的成员
if (bList.isEmpty()) {
return false;
}
if (bList.peek() > t) {
// 本身已可战胜
bList.poll();
} else {
// 检查增加能量包是否可战胜
if (p < 1) {
return false;
}
// 贪心:增加能量包后,查找最小能满足出战的成员
bList.pollLast();
p--;
}
}
return true;
}
01-16
1557

05-18
2319

05-19
190
