413周赛·第三题 - 3276. 选择矩阵中单元格的最大得分

题目链接 3276. 选择矩阵中单元格的最大得分
思路 动态规划
题解链接 枚举值域,状压行号,附费用流做法(Python/Java/C++/Go)
关键点 1. 状态定义 - \(i\)为矩阵中的数字,\(j\)为使用的行号 2. 状态压缩 - 枚举行号(位运算)
时间复杂度 \(O(mn2^m)\)
空间复杂度 \(O(mn + 2^m)\)

代码实现:

class Solution:
    def maxScore(self, grid: List[List[int]]) -> int:
        # val -> position
        position = defaultdict(list)
        for i, row in enumerate(grid):
            for x in set(row):
                position[x].append(i)
        # 只考虑在 grid 中的元素
        all_nums = list(position)
    
        @cache
        def dfs(i, j):
            if i < 0:
                return 0
            # 不选 x
            answer = dfs(i-1, j)
            for k in position[all_nums[i]]:
                if (j >> k & 1) == 0:
                    answer = max(answer, all_nums[i] + dfs(i-1, j | 1 << k))
            return answer
        
        return dfs(len(all_nums)-1, 0)
Python-动态规划-常数优化-1. 从大到小递归 2. 优选贪心
class Solution:
    def maxScore(self, grid: List[List[int]]) -> int:
        # val -> position
        position = defaultdict(list)
        for i, row in enumerate(grid):
            for x in set(row):
                position[x].append(i)
        # 下面从大到小递归
        all_nums = sorted(position)
    
        @cache
        def dfs(i, j):
            if i < 0:
                return 0
            # 如果循环结束后 answer > 0,就不再递归不选的情况
            answer = 0
            for k in position[all_nums[i]]:
                if (j >> k & 1) == 0:
                    answer = max(answer, all_nums[i] + dfs(i-1, j | 1 << k))
            return answer if answer else dfs(i-1, j)
        
        return dfs(len(all_nums)-1, 0)
posted @ 2024-09-09 02:33  WrRan  阅读(13)  评论(0)    收藏  举报