力扣 黃金礦工

2021-10-08 17:48:47 字數 3594 閱讀 7088

你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 m * n 的網格 grid 進行了標註。每個單元格中的整數就表示這一單元格中的**數量;如果該單元格是空的,那麼就是 0。

為了使收益最大化,礦工需要按以下規則來開採**:

每當礦工進入乙個單元,就會收集該單元格中的所有**。

礦工每次可以從當前位置向上下左右四個方向走。

每個單元格只能被開採(進入)一次。

不得開採(進入)**數目為 0 的單元格。

礦工可以從網格中 任意乙個 有**的單元格出發或者是停止。

示例 1:

輸入:grid = [[0,6,0],[5,8,7],[0,9,0]]

輸出:24

解釋:[[0,6,0],

[5,8,7],

[0,9,0]]

一種收集最多**的路線是:9 -> 8 -> 7。

示例 2:

輸入: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。

1 <= grid.length, grid[i].length <= 15

0 <= grid[i][j] <= 100

最多 25 個單元格中有**。

題意:1.金礦不為0的才可以進入

2.金礦不能重複進入

思路:1.找到哪些點可以是起點

2.遍歷每個起點的所有路徑,找出最大值

解決:起點(邊界點和左下角點):

1.起點必須不為零;

2.並且為了減少不必要執行,應該將一條路徑的子路省去,這就要求我們把邊界點(有零個或乙個非零相鄰金礦的點)當作起點

3.同時考慮當路徑是迴路時,沒有邊界點,所以只把左下角的點(有兩個相鄰節點,並且上邊,右邊有金礦)當起點。(當然,右下,左上,左下角都行)

3.有3,4個非零相鄰金礦的點為起點,必定不會是最大值(你可以試試)

回溯找最大值:

1.終點:當上下左右不含非零點時為終點,此時比較並記錄現最大值。

2.遍歷路線:當發現某乙個臨點非零,便進入。為了防止發生迴路,進入前需要將此點值變為零即可。遍歷後恢復其原值,一邊其他起點遍歷。

class

solution

:def

getmaximumgold

(self, grid: list[list[

int]])

->

int:

#當該點非零,並且為邊界點或左下角點時返回ture

defbegin

(i,j)

:if grid[i]

[j]:

#**值非零是起點的第乙個條件

num=

0for p,q in

zip(

[i-1

,i+1

,i,i]

,[j,j,j-

1,j+1]

):#記錄他又幾個相鄰非零節點if0

<=p0<=q[q]:

num+=

1if num<=1:

#乙個或0個,是邊界點,可以當起點

return

true

if num==

2and

0<=i-

11[j]and grid[i]

[j+1]:

#兩個並且在上邊和右邊是左下角點,可以當起點

return

true

return

false

#值為零,或有3,4非零相鄰節點不是起點

#遍歷每個起點的所有路徑

defdg

(i,j,max_now)

: over=

true

#true,說明相鄰點都沒有**,終點

for p,q in

zip(

[i-1

,i+1

,i,i]

,[j,j,j-

1,j+1]

):#觀察上下左右if0

<=p0<=q[q]:

#相鄰點存在,且有**嗎?

grid_old=grid[p]

[q]#挖相鄰點**值

grid[p]

[q]=

0#相鄰點**為0

dg(p,q,max_now+grid_old)

#增加金值,並進入此相鄰點

grid[p]

[q]=grid_old#相鄰點探索完畢,恢復其原始值,一邊下一起點探索

over=

false

#false,說明相鄰點有**,非終點

if over:

#此點是終點嗎

self.

max=

max(self.

max,max_now)

#比較原最大值,記錄最大

#行列,最大值

m=len(grid)

n=len(grid[0]

) self.

max=

0#遍歷所有點,如果是起點則遍歷所有路徑

for i in

range

(m):

for j in

range

(n):

if begin(i,j)

:#是起點嗎?

grid_old=grid[i]

[j]#挖起點**值

grid[i]

[j]=

0#起點**為零

dg(i,j,grid_old)

#以起點開始,增加金值,進入起點

grid[i]

[j]=grid_old#相鄰點探索完畢,恢復其原始值,一邊下一起點探索

return self.

max#返回最大值

相關:

zip() 函式用於將可迭代的物件作為引數,將物件中對應的元素打包成乙個個元組,然後返回由這些元組組成的列表。

例:

>>

>a =[1

,2,3

]>>

> b =[4

,5,6

]>>

> c =[4

,5,6

,7,8

]>>

> zipped =

zip(a,b)

# 打包為元組的列表[(

1,4)

,(2,

5),(

3,6)

]>>

>

zip(a,c)

# 元素個數與最短的列表一致[(

1,4)

,(2,

5),(

3,6)

]>>

>

zip(

*zipped)

# 與 zip 相反,*zipped 可理解為解壓,返回二維矩陣式[(

1,2,

3),(

4,5,

6)]

leetcode 黃金礦工

你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 m n 的網格 grid 進行了標註。每個單元格中的整數就表示這一單元格中的 數量 如果該單元格是空的,那麼就是 0。為了使收益最大化,礦工需要按以下規則來開採 每當礦工進入乙個單元,就會收集該單元格中的所有 礦工每次可以從當...

黃金礦工 回溯演算法

你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 m n 的網格 grid 進行了標註。每個單元格中的整數就表示這一單元格中的 數量 如果該單元格是空的,那麼就是 0。為了使收益最大化,礦工需要按以下規則來開採 示例 2 輸入 grid 1,0,7 2,0,6 3,4,5 0...

ZCMU2165黃金礦工

初步分析 這題是一道加了約束條件的01揹包問題,約束條件是同一條直線上的 必須要按順序挖。twice分析 約束條件就是假如有c1 c2 c3三個同一直線上的 假設c1先給出 下面再對 給出解釋。include define mem a,b memset a,b,sizeof a using name...