一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情。
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【LeetCode 1626. 无矛盾的最佳球队 】- JavaScript(排序+动态规划)
题意描述
假设你是球队的经理。对于即将到来的锦标赛,你想组合一支总体得分最高的球队。球队的得分是球队中所有球员的分数 总和 。
然而,球队中的矛盾会限制球员的发挥,所以必须选出一支 没有矛盾 的球队。如果一名年龄较小球员的分数 严格大于 一名年龄较大的球员,则存在矛盾。同龄球员之间不会发生矛盾。
给你两个列表 scores 和 ages,其中每组 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 名球员。注意,你可以选中多个同龄球员。
思路分析:
先分析出题目本质是什么 =>
最长上升子序列,不连续。 接下来如何做
- 既然上升优先,但前提又不能年龄大的反而分数小,那就按照年龄排序
- 比如
scores = [1,2,3,5], ages = [8,9,10,1],合起来就是[[8,1][9,2][10,3][1,5]]
- 排序 :
[[1,5][8,1][9,2][10,3]]
- 最长上升子序列:按照第二列,此时成绩,已经保证后的年龄>前的,且同一年龄的是成绩升序
排序+DP
核心思想:dp的递推公式的推导,都知道动态规划最难的就是递推公式的推导了。
- 我们首先假设
dp[:i]是已经被填充好的,- 然后去研究下标为i的人的得分
socres[i]时,我们需要考虑所有阅历更小的人scores[:i]的情况。- 假设scores[j]是下标为j的队员的得分,且j<i,即j阅历小于i,只有当scores[i]>=scores[j]时,第i个队员才可以没有矛盾的加入以j结尾的球队中。
- 这时,我们必须让以i结尾的无矛盾球队的最大得分dp[i]要继承以j结尾的无矛盾球队的最大得分
dp[j],并加上新加入的队员i的得分scores[i]- 当满足条件的j可能有很多个,必须要从尝试把i队员加入到不同的以j结尾的无矛盾球队中,来进行选择情况使得dp最大。
var bestTeamScore = function (scores, ages) {
const len = scores.length
const arr = ages.map((v, i) => [v, scores[i]])
arr.sort((a, b) => {
if (a[0] < b[0]) {
return -1
}
if (a[0] === b[0]) {
return a[1] - b[1]
}
return 1
})
let ans = 0
console.log(arr)
const dp = new Array(len).fill(0)
for (let i = 0; i < len; i++) {
dp[i] = arr[i][1]
for (let j = 0; j < i; j++) {
if (arr[j][1] <= arr[i][1]) {
dp[i] = Math.max(dp[i], dp[j] + arr[i][1])
}
}
ans = Math.max(ans, dp[i])
}
return ans
};
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤