413周賽·第三題 - 3276. 選擇矩陣中單元格的最大得分

WrRan發表於2024-09-09
題目連結 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)

相關文章