LeetCode 摘櫻桃(動態規劃)

2021-09-20 15:30:09 字數 2447 閱讀 4002

乙個n x n的網格(grid) 代表了一塊櫻桃地,每個格仔由以下三種數字的一種來表示:

0 表示這個格仔是空的,所以你可以穿過它。

1 表示這個格仔裡裝著乙個櫻桃,你可以摘到櫻桃然後穿過它。

-1 表示這個格仔裡有荊棘,擋著你的路。

你的任務是在遵守下列規則的情況下,盡可能的摘到最多櫻桃:

從位置 (0, 0) 出發,最後到達 (n-1, n-1) ,只能向下或向右走,並且只能穿越有效的格仔(即只可以穿過值為0或者1的格仔);

當到達 (n-1, n-1) 後,你要繼續走,直到返回到 (0, 0) ,只能向上或向左走,並且只能穿越有效的格仔;

當你經過乙個格仔且這個格仔包含乙個櫻桃時,你將摘到櫻桃並且這個格仔會變成空的(值變為0);

如果在 (0, 0) 和 (n-1, n-1) 之間不存在一條可經過的路徑,則沒有任何乙個櫻桃能被摘到。

示例 1:

輸入: grid =

[[0, 1, -1],

[1, 0, -1],

[1, 1, 1]]

輸出: 5

解釋:

玩家從(0,0)點出發,經過了向下走,向下走,向右走,向右走,到達了點(2, 2)。

在這趟單程中,總共摘到了4顆櫻桃,矩陣變成了[[0,1,-1],[0,0,-1],[0,0,0]]。

接著,這名玩家向左走,向上走,向上走,向左走,返回了起始點,又摘到了1顆櫻桃。

在旅程中,總共摘到了5顆櫻桃,這是可以摘到的最大值了。

說明:

grid 是乙個 n * n 的二維陣列,n的取值範圍是1 <= n <= 50。

每乙個 grid[i][j] 都是集合 其中的乙個數。

可以保證起點 grid[0][0] 和終點 grid[n-1][n-1] 的值都不會是 -1。

思路分析:首先我們知道一條路徑從前往後走和從後往前走獲取的櫻桃數是相同的,所以正反走可以看做為兩次正走。

剛開始吧,可能大家都會想著把兩次路徑分開,先走一次獲取最大,然後把走過摘取了的櫻桃去掉,在走一次獲取當前最大的櫻桃,最後返回兩個結果的和。這樣看似沒有問題,其實邏輯是存在漏洞的,因為第一次走過的路徑會影響第二次的路徑。比如:

綠色為第一次走過的獲取最大櫻桃數路徑13,藍色為第一次獲取最大後可獲取的最大櫻桃數1,總共14.

然而這個矩陣的解為15

所以我們不能分開求解,需要用兩個人同時在矩陣中行走。如果兩個人在同乙個位置,則這個位置也只能採摘一次,否則兩個人所處的位置都能進行櫻桃採摘。

由於矩陣的大小是固定的,所以從左上角到右下角在題中的行走規則需要的總步數也是固定的,為gridsize * 2 - 1。

在第step步,假設第乙個人在(onerow, onecol),第二個人走到(tworow, twocol),那麼一定有onerow + onecol == step,tworow + twocol == step.

如果onerow == tworow,兩個人所處的位置相同,否則兩個人所處的位置不相同。位置相同時,這個位置只能採摘一次,位置不同兩個人所處的位置都進行採摘。

狀態轉移方程:

dp[onerow][towrow] = grid[onerow][onecol] + grid[towrow][twocol] + max(dp[onerow - 1][towrow], dp[onerow][towrow - 1], dp[onerow - 1][towrow - 1])
class

solution

//第一步:首先將step-1步可獲得的櫻桃數放到step步

if(onerow >0)

if(towrow >0)

if(onerow >

0&& towrow >0)

//如果在step - 1遇到了障礙,則step步無法行走

if(dp[onerow]

[towrow]==-

1)//第二步:摘取第step步兩個人所處的位置上的櫻桃(注意當兩個人在同乙個位置時,只能摘一次)

陶陶 摘蘋果 動態規劃

陶陶摘 蘋果陶陶摘蘋果 陶陶摘蘋果 on問題轉化 數軸上 有若干點 從m個 固定區間 中選出k 個,要求 覆蓋點數 最多.數軸上有若干點,從m個固定區間中選出k個,要求覆蓋點數最多.數軸上有若干 點,從m 個固定區 間中選出 k個,要 求覆蓋點 數最多.然後排序進行 dpdp dp,f i j f ...

陶陶 摘蘋果 動態規劃

陶陶摘 蘋果陶陶 摘蘋果 desc ript iond escr ipti onso luti onso luti on問題轉化 數軸上 有若干點 從m個 固定區間 中選出k 個,要求 覆蓋點數 最多.數 軸上有若 幹點,從 m個固定 區間中選 出k個,要求覆蓋 點數最多 然後排序進行 dpd p,...

UPC 5843 摘櫻桃 最優狀態遞推

很難想到的最優狀態遞推,一開始總在如何分組的問題上糾結。其實只需要在分配第i個櫻桃時,將其與前乙個 j i 1 分為一組 前兩個分為一組 j i 2 前三個分為一組 j i 3 然後取剩下j個的最優分配情況dp j 求和取最小值即可。dp j 表示了當有j個櫻桃時的最優解分配。是做了 t且平方處理的...