題目:在乙個m×
\times
×n的期盼的每乙個都放有乙個禮物,每個禮物都有一定的價值。你可以從棋盤的左上角開始拿格仔裡的禮物,並每次向左或者向下移動一格,直到達到棋盤的右下角。給定乙個棋盤及其上面的禮物,請計算你最多能拿到多少價值的禮物?
例如,在下面的棋盤中,可以拿到最大價值為53的禮物對於這個問題,開始的思路就是回溯法,求出從左上角開始所有能到達右下角的路徑,並計算這條路徑上的長度,並維護乙個max_path,最終返回的max_path值為最後的最大價值,**如下:1 10 3 8
12 2 9 6
5 7 4 11
5 7 16 5
def
find_path
(nums)
: rows =
len(nums)
cols =
len(nums[0]
) visited =[[
0for i in
range
(cols)
]for j in
range
(rows)
] max_num =
0 count =
0 find_max_path(nums,0,
0, rows, cols, visited, max_num, count)
return max_num[0]
deffind_max_path
(nums, row, col, rows, cols, visited, max_num, count)
:# 終止條件,意思是到達邊界重點
# 此時需要比較並更新路徑最大值
if row == rows -
1and col == cols -1:
count += nums[row]
[col]
if max_num < count:
max_num = count
return
visited[row]
[col]=1
count += nums[row]
[col]
if row < rows -
1and visited[row +1]
[col]!=1
: find_max_path(nums, row +
1, col, rows, cols, visited, max_num, count)
if col < cols -
1and visited[row]
[col +1]
!=1: find_max_path(nums, row, col +
1, rows, cols, visited, max_num, count)
visited[row]
[col]
=0
這是開始寫出的**,是個錯誤的**,其錯誤原因就是並不能通過max_num = count的語句來使max_num的值得到更新,儘管在當前棧裡的max_num已經更新,但是在賦值時其實是產生了乙個新的max_num,如果跟蹤max_num的id可以發現,max_num的id在賦值時發生變化,這個新的max_num並不會影響到上乙個呼叫棧裡max_num的值,因此在遞迴中這樣改變乙個整數的值不可行。
需要通過其他的辦法來儲存之前max_num的值,並且讓這個對所有的函式棧都可見且不變,想到之前寫遍歷樹的路徑及全排列的題目,需要儲存最終答案時都是使用的list,因此將max_num轉化為list來更新。list本身就是可變的,更改其中的元素數值不會改變list的id,因此對於所有的棧全程可見。
def
find_path
(nums)
: rows =
len(nums)
cols =
len(nums[0]
) visited =[[
0for i in
range
(cols)
]for j in
range
(rows)
] max_num =[0
] count =
0 find_max_path(nums,0,
0, rows, cols, visited, max_num, count)
return max_num[0]
deffind_max_path
(nums, row, col, rows, cols, visited, max_num, count)
:# 終止條件,意思是到達邊界重點
# 此時需要比較並更新路徑最大值
if row == rows -
1and col == cols -1:
count += nums[row]
[col]
if max_num[0]
< count:
max_num[0]
= count
return
visited[row]
[col]=1
count += nums[row]
[col]
if row < rows -
1and visited[row +1]
[col]!=1
: find_max_path(nums, row +
1, col, rows, cols, visited, max_num, count)
if col < cols -
1and visited[row]
[col +1]
!=1: find_max_path(nums, row, col +
1, rows, cols, visited, max_num, count)
visited[row]
[col]
=0
這是我對這題的思路,但這個思路放在筆試裡感覺大概率超時,遞迴多,確實有點慢,參考《劍指offer》中動態規劃的思路,遞推公式為:
f (i
,j)=
max(
f(i−
1,j)
,f(i
,j−1
))+g
ift[
i,j]
f(i,j)=max(f(i-1,j),f(i,j-1)) + gift[i,j]
f(i,j)
=max
(f(i
−1,j
),f(
i,j−
1))+
gift
[i,j
]公式挺好理解的,這裡子問題的座標是從小到大,因此迴圈從前面開始就可以。
def
find_path
(nums)
: rows =
len(nums)
cols =
len(nums[0]
) max_values =[[
0for i in
range
(cols)
]for j in
range
(rows)
]for i in
range
(rows)
:for j in
range
(cols)
: up, left =0,
0if i >0:
up = max_values[i -1]
[j] left = max_values[i]
[j -1]
max_values[i]
[j]=
max(up, left)
+ nums[i]
[j]return max_values[-1
][-1
]
不論是**量還是寫起來的順暢程度,都比回溯法簡單太多了。 禮物的最大價值
題目 在乙個mxn的棋盤的每乙個都放有乙個禮物,每個禮物都有一定的價值 價值大於0 你可以從棋盤的左上角開始拿格仔裡的禮物,並每次向右或者向下移動一格,知道到達棋盤的右下角。給定乙個棋盤及其上面的禮物,請計算你最多能達到多少價值的禮物。方法一 動態規劃 二維陣列儲存 int getmaxvalue ...
禮物的最大價值
題目 在乙個m n的棋盤的每一格都放有乙個禮物,每個禮物都有一定的價值 價值大於0 你可以從棋盤的左上角開始拿格仔裡的禮物,並每次向左或者向下移動一格直到到達棋盤的右下角。給定乙個棋盤及其上面的禮物,請計算你最多能拿到多少價值的禮物?動態規劃,優化前 int getmaxvalue const in...
禮物的最大價值
面試題47 禮物的最大價值 題目 在乙個m n的棋盤的每一格都放有乙個禮物,每個禮物都有一定的價值 價值大於0 你可以從棋盤的左上角開始拿格仔裡的禮物,並每次向右或 者向下移動一格直到到達棋盤的右下角。給定乙個棋盤及其上面的禮物,請計 算你最多能拿到多少價值的禮物?static int get ma...