You are given two integer arrays scores
and ages
, both of length n
, where scores[i]
and ages[i]
represent the score and age of the i
-th player, respectively.
You want to choose a team of any size (including possibly all players) with the following constraint: for any two players in the team, if one player is younger than the other, then the younger player's score must not be strictly greater than the older player's score. In other words, there must be no "conflict" where a younger player has a higher score than an older player.
Your task is to select a team (possibly empty) with the maximum total score, following the above rule. You may not reuse any player in the team.
Key Constraints:
At first glance, this problem seems similar to classic subset or team selection problems, but the conflict constraint (no younger player with a higher score than an older one) makes it tricky. A brute-force approach would consider all possible subsets and check if they are valid, but this quickly becomes infeasible as the number of players grows (exponential time).
The key insight is that the conflict rule is about the relationship between age and score within the team. If we can process the players so that for any chosen sequence, the scores don't increase as ages decrease, we avoid conflicts. This is reminiscent of the Longest Increasing Subsequence (LIS) problem, but with two dimensions (age and score).
We need to find an efficient way to build up the best team, possibly by sorting and using dynamic programming to keep track of the best results.
To solve the problem efficiently, we use the following steps:
(age, score)
for each player.i
in the sorted list, compute dp[i]
as the maximum team score ending with player i
.dp[i]
to the player's own score (team of just themselves).j
(where j < i
), if score[j] <= score[i]
, we can safely add player i
to the team ending at j
(no conflict).dp[i] = max(dp[i], dp[j] + score[i])
for all such j
.dp
array, representing the best team score possible.This approach is efficient because:
Let's consider the following example:
scores = [4, 5, 6, 5]
ages = [2, 1, 2, 1]
[(2,4), (1,5), (2,6), (1,5)]
[(1,5), (1,5), (2,4), (2,6)]
dp = [5, 5, 4, 6]
dp[1] = max(5, 5+5) = 10
dp[3] = max(6, 5+6) = 11
dp[3] = max(11, 10+6) = 16
dp[3] = max(16, 4+6) = 16
dp
: [5, 10, 4, 16]
16
. The best team score is 16.class Solution:
def bestTeamScore(self, scores, ages):
players = sorted(zip(ages, scores))
n = len(players)
dp = [0] * n
for i in range(n):
dp[i] = players[i][1]
for j in range(i):
if players[j][1] <= players[i][1]:
dp[i] = max(dp[i], dp[j] + players[i][1])
return max(dp)
class Solution {
public:
int bestTeamScore(vector<int>& scores, vector<int>& ages) {
int n = scores.size();
vector<pair<int, int>> players;
for (int i = 0; i < n; ++i)
players.push_back({ages[i], scores[i]});
sort(players.begin(), players.end());
vector<int> dp(n, 0);
int res = 0;
for (int i = 0; i < n; ++i) {
dp[i] = players[i].second;
for (int j = 0; j < i; ++j) {
if (players[j].second <= players[i].second) {
dp[i] = max(dp[i], dp[j] + players[i].second);
}
}
res = max(res, dp[i]);
}
return res;
}
};
class Solution {
public int bestTeamScore(int[] scores, int[] ages) {
int n = scores.length;
int[][] players = new int[n][2];
for (int i = 0; i < n; ++i) {
players[i][0] = ages[i];
players[i][1] = scores[i];
}
Arrays.sort(players, (a, b) -> a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]);
int[] dp = new int[n];
int res = 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]);
}
}
res = Math.max(res, dp[i]);
}
return res;
}
}
var bestTeamScore = function(scores, ages) {
let players = [];
for (let i = 0; i < scores.length; i++) {
players.push([ages[i], scores[i]]);
}
players.sort((a, b) => a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
let n = players.length;
let dp = new Array(n).fill(0);
let res = 0;
for (let i = 0; i < n; i++) {
dp[i] = players[i][1];
for (let j = 0; j < i; j++) {
if (players[j][1] <= players[i][1]) {
dp[i] = Math.max(dp[i], dp[j] + players[i][1]);
}
}
res = Math.max(res, dp[i]);
}
return res;
};
Brute-Force Approach:
The sort step is O(n log n), but the DP dominates for large n.
The "Best Team With No Conflicts" problem is elegantly solved using dynamic programming after a strategic sort by age and score. The conflict constraint is managed by always processing players from youngest to oldest, and only extending teams where the score order is non-decreasing. This approach is both efficient and conceptually clear, leveraging classic DP techniques for subset selection with constraints.