LC-1626. 无矛盾的最佳球队(排序+LIS)
创始人
2025-06-01 15:07:56

文章目录

    • [1626. 无矛盾的最佳球队](https://leetcode.cn/problems/best-team-with-no-conflicts/)
      • 法一:排序 + 和最大的子序列问题
      • 法二:排序 + 树状数组(基于值域计算)

1626. 无矛盾的最佳球队

难度中等81收藏分享切换为英文接收动态反馈

假设你是球队的经理。对于即将到来的锦标赛,你想组合一支总体得分最高的球队。球队的得分是球队中所有球员的分数 总和

然而,球队中的矛盾会限制球员的发挥,所以必须选出一支 没有矛盾 的球队。如果一名年龄较小球员的分数 严格大于 一名年龄较大的球员,则存在矛盾。同龄球员之间不会发生矛盾。

给你两个列表 scoresages,其中每组 scores[i]ages[i] 表示第 i 名球员的分数和年龄。请你返回 所有可能的无矛盾球队中得分最高那支的分数

示例 1:

输入:scores = [1,3,5,10,15], ages = [1,2,3,4,5]
输出:34
解释:你可以选中所有球员。

示例 2:

输入:scores = [4,5,6,5], ages = [2,1,2,1]
输出:16
解释:最佳的选择是后 3 名球员。注意,你可以选中多个同龄球员。

示例 3:

输入:scores = [1,2,3,5], ages = [8,9,10,1]
输出:6
解释:最佳的选择是前 3 名球员。

提示:

  • 1 <= scores.length, ages.length <= 1000
  • scores.length == ages.length
  • 1 <= scores[i] <= 106
  • 1 <= ages[i] <= 1000

法一:排序 + 和最大的子序列问题

按照年龄从小到大排序, 此时满足了【一名年龄较小球员的分数 严格大于 一名年龄较大的球员】的要求,余下只要求和最大的子序列,(最长递增子序列变形题)

class Solution {public int bestTeamScore(int[] scores, int[] ages) {int n =scores.length;int[][] zip = new int[n][2];for(int i = 0; i < n; i++){zip[i][0] = scores[i];zip[i][1] = ages[i];}// 按照年龄排序Arrays.sort(zip, (a, b) -> a[1] == b[1] ? a[0] - b[0] : a[1] - b[1]);// 找得分单调递增最大的序列和 (求和最大的递增子序列, 允许有相同元素)int[] dp = new int[n+1];for(int i = 0; i < n; i++){dp[i] = zip[i][0]; // 初始化,每个i位置上最大和是自己}int res = dp[0];for(int i = 0; i < n; i++){for(int j = 0; j < i; j++){//将和作为衡量标准,而不是递增子序列的长度。(允许重复)if(zip[i][0] >= zip[j][0] && dp[i] < dp[j] + zip[i][0]){dp[i] = dp[j] + zip[i][0];}res = Math.max(res, dp[i]);}}return res;}
}

法二:排序 + 树状数组(基于值域计算)

https://leetcode.cn/problems/best-team-with-no-conflicts/solution/python3javacgo-yi-ti-shuang-jie-pai-xu-d-osaj/

与方法一类似,我们可以将球员按照分数从小到大排序,如果分数相同,则按照年龄从小到大排序。

接下来,我们使用树状数组维护不超过当前球员年龄的球员的最大得分。每一次,我们只需要在 O(logn) 的时间内找出不超过当前球员年龄的球员的最大得分,然后将当前球员的分数加到该得分上,即可更新当前球员年龄的最大得分。

最后,我们返回得分的最大值即可。

class Solution {public int bestTeamScore(int[] scores, int[] ages) {int n = ages.length;int[][] arr = new int[n][2];for(int i = 0; i < n; i++){arr[i] = new int[]{scores[i], ages[i]};}// 我们可以将球员按照分数从小到大排序,如果分数相同,则按照年龄从小到大排序。Arrays.sort(arr, (a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);int m = 0;for(int age : ages) m = Math.max(m, age);// 我们使用树状数组维护不超过当前球员年龄的球员的最大得分。BinaryIndexedTree tree = new BinaryIndexedTree(m);// 每一次,我们只需要在 O(logn) 的时间内找出不超过当前球员年龄的球员的最大得分,// 然后将当前球员的分数加到该得分上,即可更新当前球员年龄的最大得分。for(int[] x : arr){tree.update(x[1], x[0] + tree.query(x[1]));}return tree.query(m);}
}class BinaryIndexedTree{private int n;private int[] c;public BinaryIndexedTree(int n){this.n = n;c = new int[n + 1];}public void update(int x, int val){while(x <= n){c[x] = Math.max(c[x], val);x += x & -x;}}public int query(int x) {int s = 0;while (x > 0) {s = Math.max(s, c[x]);x -= x & -x;}return s;}
}

相关内容

热门资讯

中茶九十年代老茶品鉴会圆满成功 12月23日,【老韵新生·品味岁月】中茶九十年代老茶品鉴会于中茶普洱中国铁建西派国际中心中茶普洱体验...
汾酒跨界再推年度力作 “淮味汾... 2025年12月25日,山西朔州老城南大街汾酒老作坊酒馆内,一场别开生面的新品发布活动隆重举行——“...
天冷后别频繁洗澡,可以多泡脚,... 2025、12、26日 题目:天冷后别频繁洗澡,可以多泡脚,泡脚更符合“温而不燥”养生理念 作者:杨...
你家杀猪们要喊我…… 宣威的“宰猪饭”(也叫“杀猪饭”或“年猪饭”)远不止是一顿饭,它是一场从冬至持续到春节的、承载着丰收...