題目連結 | 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)