LC 1626. 无矛盾的最佳球队

https://leetcode-cn.com/problems/best-team-with-no-conflicts/

回溯肯定是不行的,之后就想到了动态规划。动态规划主要关注状态,基于当前状态如何扩展/更新其他状态。这侧面说明动态规划从在某种计算顺序性,我们大家经常说有子问题最优解结构。这题的一个启示就是,如果题目中含有某种顺序性,就可以尝试动态规划。

这个问题有个隐式顺序性就是年龄和能力的关系,一旦选择了某个年龄下的能力X,那么之后的能力决不能低于X(同年龄除外)。或者换个角度考虑,一旦选择了某个能力下的年龄Y,那么之后的年龄决不能低于Y(同能力的除外)

如果按照第一种思路,得到的解法就是

class Solution:
    def bestTeamScore(self, scores: List[int], ages: List[int]) -> int:
        n = len(scores)
        xs = list(zip(ages, scores))
        xs.append((0, 0))
        xs.sort()

        dp = [0] * (n + 1)
        dp[0] = 0
        for i in range(n + 1):
            for j in range(i + 1, n + 1):
                if xs[j][0] == xs[i][0] or xs[j][1] >= xs[i][1]:
                    dp[j] = max(dp[j], dp[i] + xs[j][1])
        ans = max(dp)
        return ans

如果按照第二种思路,得到的解法就是

class Solution2:
    def bestTeamScore(self, scores: List[int], ages: List[int]) -> int:
        n = len(scores)
        xs = list(zip(scores, ages))
        xs.append((0, 0))
        xs.sort()

        dp = [0] * (n + 1)
        dp[0] = 0
        for i in range(n + 1):
            for j in range(i + 1, n + 1):
                if xs[j][0] == xs[i][0] or xs[j][1] >= xs[i][1]:
                    dp[j] = max(dp[j], dp[i] + xs[j][0])
        ans = max(dp)
        return ans