无矛盾的最佳球队
难度:
标签:
题目描述
代码结果
运行时间: 100 ms, 内存: 16.3 MB
/*
* 思路:
* 1. 将球员按年龄和分数排序,以便处理无矛盾的选择。
* 2. 使用动态规划(DP)方法来计算最佳得分。
* 3. dp[i] 表示选择第 i 名球员时的最佳得分。
* 4. 对于每个球员 i,检查之前的每个球员 j,如果没有矛盾,则更新 dp[i]。
*/
import java.util.Arrays;
import java.util.stream.IntStream;
public class BestTeamScoreStream {
public int bestTeamScore(int[] scores, int[] ages) {
int n = scores.length;
int[][] players = IntStream.range(0, n)
.mapToObj(i -> new int[]{ages[i], scores[i]})
.sorted((a, b) -> (a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]))
.toArray(int[][]::new);
int[] dp = new int[n];
int maxScore = 0;
for (int i = 0; i < n; i++) {
dp[i] = players[i][1];
for (int j = 0; j < i; j++) {
if (players[j][1] <= players[i][1]) {
dp[i] = Math.max(dp[i], dp[j] + players[i][1]);
}
}
maxScore = Math.max(maxScore, dp[i]);
}
return maxScore;
}
public static void main(String[] args) {
BestTeamScoreStream bts = new BestTeamScoreStream();
int[] scores1 = {1, 3, 5, 10, 15};
int[] ages1 = {1, 2, 3, 4, 5};
System.out.println(bts.bestTeamScore(scores1, ages1)); // 输出:34
int[] scores2 = {4, 5, 6, 5};
int[] ages2 = {2, 1, 2, 1};
System.out.println(bts.bestTeamScore(scores2, ages2)); // 输出:16
int[] scores3 = {1, 2, 3, 5};
int[] ages3 = {8, 9, 10, 1};
System.out.println(bts.bestTeamScore(scores3, ages3)); // 输出:6
}
}
解释
方法:
本题解采用了结合排序和树状数组(Binary Indexed Tree, BIT)的动态规划方法。首先,通过将球员按照年龄排序(如果年龄相同则按分数排序),确保能够以非降序处理球员。这样,在处理每个球员时,可以保证其之前的球员要么年龄小于等于当前球员,要么年龄相同但分数不大于当前球员。然后,使用树状数组来维护不同年龄下可达到的最高分数总和。对于每个球员,通过树状数组查询当前年龄可达到的最大分数,并更新该年龄的分数总和。最后,通过查询最大年龄的信息,得到最大分数总和。
时间复杂度:
O(n log n + n log(maxAge))
空间复杂度:
O(maxAge + n)
代码细节讲解
🦆
在题解中,为什么首先需要将球员按照年龄和分数进行排序?排序的具体规则是什么,即当年龄相同时分数如何排序?
▷🦆
题解中提到使用树状数组(Binary Indexed Tree, BIT)来维护最高分数总和,树状数组中每个位置代表的具体含义是什么?
▷🦆
在使用树状数组的查询和更新操作中,查询函数`query()`的实现逻辑是什么,它如何确保能获取到当前年龄最大的分数总和?
▷🦆
更新函数`update()`在树状数组中的作用是什么,它是如何确保树状数组中存储的是某个年龄下的最高分数总和的?
▷