原题链接
华为OD机试真题-游戏分组-2023年OD统一考试(C卷)_王者荣耀游戏分组绝对值-CSDN博客
思路
推导思路
先统计数组中所有的评分总和
随机五人组成A队,A队总评分.
另一队B队,总评分
假设A队总是水平不高于B队,即
要求得两组实力差的最小绝对值,即
所以,要使得ans最大,就使得满足条件的a值最大,即中,找到a的最大值
背包问题
可以理解为,有10个数,需要选取5个数,背包的容量是sum/2,最多能拿多少.
java代码实现
递归入口
private static int solution(int[] arr) {
//需要拿5个数
int need = 5;
//统计总和
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
//背包容量
int bag = sum / 2;
//可以拿到的最大值
int result = process(arr, 0, bag, need);
//返回结果
return sum - 2 * result;
}
递归代码
/**
* @param arr
* @param index index表示当前要考虑选择或者不选择的队员
* @param bag 剩余容量
* @param need 需要选几个人
* @return
*/
private static int process(int[] arr, int index, int bag, int need) {
//拿满了,背包为负是上次拿多了,需要告诉上次不要拿,背包为0是上次刚好拿满
if (bag < 0) {
return -1;
}
//拿满了,背包为负是上次拿多了,需要告诉上次不要拿,背包为0是上次刚好拿满
if (need < 0) {
return -1;
}
//数组越界,这个判断应该放到最后,如果放到最前,即使当前背包已经溢出了,仍然可以拿到让背包溢出的那个值.
if (index > 9) {
return 0;
}
//不拿
int possible1 = process(arr, index + 1, bag, need);
//拿
int nextValue = process(arr, index + 1, bag - arr[index], need - 1);
int possbile2 = nextValue == -1 ? 0 : arr[index] + nextValue;
//返回最大值
return Math.max(possible1, possbile2);
}
主函数
public static void main(String[] args) {
int result1 = solution(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10});
System.out.println(result1);
}
运行结果
1
Process finished with exit code 0