题目给出 n 名球员的分数和年龄数组 scores 和 ages,其中 scores}[i] 和 ages}[i] 分别为球员 i 的分数和年龄。当一名年龄较小球员的分数严格大于一名年龄较大的球员,则存在矛盾。同龄球员之间不会发生矛盾。球队的得分是球队中所有球员分数的总和,现在我们需要求所有可能的无矛盾的球队的最高分数。
首先我们将所有队员按照分数升序进行排序,分数相同时,则按照年龄升序进行排序,我们用数组 people}[n][2] 来表示排序后的 n 名球员信息,其中 people}[i][0],people}[i][1] 分别为排序后第 i 名球员的分数和年龄。然后我们可以用动态规划来解决该问题,设 dp}[i] 为我们最后组建的球队中的最大球员序号为排序后的第 i 名球员时的球队最大分数(此时的球员序号为排序后的新序号),因为我们是按照分数升序排序的,所以最后组建球队的最后一名球员的分数一定不会小于队伍中该球员前面一名球员的分数,所以为了避免矛盾的产生我们只需要让最后组建球队的最后一名球员的年龄不小于该球员前面一名球员的年龄即可,那么转移的方程如下:
intbestTeamScore(int* scores, int scoresSize, int* ages, int agesSize) { int n = scoresSize; int people[n][2]; for (int i = 0; i < n; ++i) { people[i][0] = scores[i]; people[i][1] = ages[i]; } qsort(people, n, sizeof(people[0]), cmp); int dp[n]; int res = 0; memset(dp, 0, sizeof(dp)); for (int i = 0; i < n; ++i) { for (int j = i - 1; j >= 0; --j) { if (people[j][1] <= people[i][1]) { dp[i] = MAX(dp[i], dp[j]); } } dp[i] += people[i][0]; res = MAX(res, dp[i]); } return res; }
classSolution { public: int max_age; vector<int> t; vector<pair<int, int>> people; intlowbit(int x){ return x & (-x); }
voidupdate(int i, int val){ for (; i <= max_age; i += lowbit(i)) { t[i] = max(t[i], val); } }
intquery(int i){ int ret = 0; for (; i > 0; i -= lowbit(i)) { ret = max(ret, t[i]); } return ret; }
intbestTeamScore(vector<int>& scores, vector<int>& ages){ max_age = *max_element(ages.begin(), ages.end()); t = vector<int>(max_age + 1, 0); int res = 0; for (int i = 0; i < scores.size(); ++i) { people.push_back({scores[i], ages[i]}); } sort(people.begin(), people.end());
for (int i = 0; i < people.size(); ++i) { int score = people[i].first, age = people[i].second, cur = score + query(age); update(age, cur); res = max(res, cur); } return res; } };
publicclassSolution { int maxAge; int[] t; int[][] people;
publicintBestTeamScore(int[] scores, int[] ages) { maxAge = ages.Max(); t = newint[maxAge + 1]; int res = 0; int n = scores.Length; people = newint[n][]; for (int i = 0; i < n; ++i) { people[i] = newint[]{scores[i], ages[i]}; } Array.Sort(people, (a, b) => a[0] != b[0] ? a[0] - b[0] : a[1] - b[1]);
for (int i = 0; i < n; ++i) { int score = people[i][0], age = people[i][1], cur = score + Query(age); Update(age, cur); res = Math.Max(res, cur); } return res; }
publicintlowbit(int x) { return x & (-x); }
publicvoidUpdate(int i, int val) { for (; i <= maxAge; i += lowbit(i)) { t[i] = Math.Max(t[i], val); } }
publicintQuery(int i) { int ret = 0; for (; i > 0; i -= lowbit(i)) { ret = Math.Max(ret, t[i]); } return ret; } }
voidupdate(int i, int val, int *t, int max_age) { for (; i <= max_age; i += lowbit(i)) { t[i] = MAX(t[i], val); } }
intquery(int i, constint *t) { int ret = 0; for (; i > 0; i -= lowbit(i)) { ret = MAX(ret, t[i]); } return ret; }
intbestTeamScore(int* scores, int scoresSize, int* ages, int agesSize) { int max_age = 0; for (int i = 0; i < agesSize; i++) { max_age = MAX(max_age, ages[i]); } int t[max_age + 1]; memset(t, 0, sizeof(t)); int res = 0; int people[scoresSize][2]; int peopleSize = scoresSize; for (int i = 0; i < scoresSize; ++i) { people[i][0] = scores[i]; people[i][1] = ages[i]; } qsort(people, peopleSize, sizeof(people[0]), cmp); for (int i = 0; i < peopleSize; ++i) { int score = people[i][0], age = people[i][1], cur = score + query(age, t); update(age, cur, t, max_age); res = MAX(res, cur); } return res; }