題面
m*n
網格 黃金礦工需要按以下規則來開採黃金,求最大
- 每當礦工進入一個單元,就會收集該單元格中的所有黃金。
- 礦工每次可以從當前位置向上下左右四個方向走。
- 每個單元格只能被開採(進入)一次。
- 不得開採(進入)黃金數目為 0 的單元格。
- 礦工可以從網格中 任意一個 有黃金的單元格出發或者是停止
輸入:grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]]
輸出:28
解釋:
[[1,0,7],
[2,0,6],
[3,4,5],
[0,3,0],
[9,0,20]]
一種收集最多黃金的路線是:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7。
思路
- 每個網格非零值都是值得開挖的起始點
- 每個(存在礦脈的)方格,都有四個方向可選下一步,即四叉樹
- 顯然相同礦格挖礦之旅只能挖一次,因此需要挖時減計,挖完回填
程式碼
func getMaximumGold(grid [][]int) int {
var ans int
var dig func(int,int, int) int
rows,cols := len(grid),len(grid[0])
xy := [4]struct{x,y int}{{0,1},{0,-1},{1,0},{-1,0}} // 方向 右,左,下,上
dig = func(x,y int, sum int) int {
if x < 0 || y < 0 || x>=rows || y >=cols || grid[x][y] == 0 {
return sum
}
t :=grid[x][y] // t 儲存礦脈g[x][y],便於回溯時候恢復現場
grid[x][y] = 0
rs := make([]int,4)
for i,o := range xy{
rs[i] = dig(x + o.x,y + o.y,sum + t)
}
grid[x][y] = t
return max(rs...) // 獲取從當前礦點出發能挖的最大礦量
}
for i:=0;i<rows;i++ {
for j:=0;j<cols;j++ {
if grid[i][j] != 0 {
if cur := dig(i,j, 0); cur > ans {
ans = cur
}
}
}
}
return ans
}
func max(vals...int) int {
var max int
for _, val := range vals {
if val > max {
max = val
}
}
return max
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結