你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 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...