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)

浙公网安备 33010602011771号