题目链接 | 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 -> positionposition = defaultdict(list)for i, row in enumerate(grid):for x in set(row):position[x].append(i)# 只考虑在 grid 中的元素all_nums = list(position)@cachedef dfs(i, j):if i < 0:return 0# 不选 xanswer = 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 answerreturn dfs(len(all_nums)-1, 0)
Python-动态规划-常数优化-1. 从大到小递归 2. 优选贪心
class Solution:def maxScore(self, grid: List[List[int]]) -> int:# val -> positionposition = defaultdict(list)for i, row in enumerate(grid):for x in set(row):position[x].append(i)# 下面从大到小递归all_nums = sorted(position)@cachedef dfs(i, j):if i < 0:return 0# 如果循环结束后 answer > 0,就不再递归不选的情况answer = 0for 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)