禮物的最大價值

2021-09-21 14:49:22 字數 4029 閱讀 6807

題目:在乙個m×

\times

×n的期盼的每乙個都放有乙個禮物,每個禮物都有一定的價值。你可以從棋盤的左上角開始拿格仔裡的禮物,並每次向左或者向下移動一格,直到達到棋盤的右下角。給定乙個棋盤及其上面的禮物,請計算你最多能拿到多少價值的禮物?

例如,在下面的棋盤中,可以拿到最大價值為53的禮物

1 10 3 8

12 2 9 6

5 7 4 11

5 7 16 5

對於這個問題,開始的思路就是回溯法,求出從左上角開始所有能到達右下角的路徑,並計算這條路徑上的長度,並維護乙個max_path,最終返回的max_path值為最後的最大價值,**如下:

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...