leetcode576 出界的路徑數

2021-10-03 18:34:44 字數 2036 閱讀 4524

題目:給定乙個 m × n 的網格和乙個球。球的起始座標為 (i,j) ,你可以將球移到相鄰的單元格內,或者往上、下、左、右四個方向上移動使球穿過網格邊界。但是,你最多可以移動 n 次。找出可以將球移出邊界的路徑數量。答案可能非常大,返回 結果 mod 10^9 + 7 的值。

一開始看題,以為類似機械人路徑問題,直接用dfs迭代n次,從起點開始,將可到達的位置入棧,判斷當前位置是否出界,若出界,路徑數量加一;反之,將它下一步可到達的位置入棧。

但是本題與以往類似(做過)的題目有些不同,本題的路徑是帶返回的,也就是說,某個點可以重複多次被訪問。這樣下來,重複計算的量就很龐大。(其實從題目中返回結果mod 10 ^ 9 + 7就看出來,計算量不小哇。)

由於方法一超時,必須想到一種帶記憶的演算法解決本題有大量重複計算的特點。那麼,動態規劃它來啦!

因為球的每一次移動都是由上一次移動的結果決定的通過累加每一次移動後,球處於邊界位置的狀態數(當球處於邊界位置的時候,下次一移動一定可以出界)並且乘以該邊界位置可從幾個方向出界(cnt<=3)。這樣可以得到最終的球出界的路徑數。

其中,動態轉移方程為:

dp[i][j][k] = dp[i-1][j][k-1] + dp[i+1][j][k-1] + dp[i][j-1][k-1] + dp[i][j+1][k-1],k為移動次數。

這裡初始化問題,為了簡便,省去討論邊界問題,初始化的矩陣要大給定矩陣一圈。這樣,在更新每個節點的值的時候,不用判斷當前橫、縱座標是否越界。

class

solution

(object):

deffindpaths

(self, m, n, n, i, j)

:"""

:type m: int

:type n: int

:type n: int

:type i: int

:type j: int

:rtype: int

"""lis =[[

[0for p in

range

(n+2)]

for q in

range

(m+2)]

] lis[0]

[i+1

][j+1]

=1#初始化,第0次移動起始節點值為1

ans =

0#路徑個數

k =0#移動次數

while k < n:

temp =[[

0for x in

range

(n+2)]

for y in

range

(m+2)]

for p in

range(1

,m+1):

for q in

range(1

,n+1):

if lis[k]

[p][q]

>0:

cnt =

0#計算可出界的方向數

if p ==1:

cnt +=

1if p == m:

cnt +=

1if q ==1:

cnt +=

1if q == n:

cnt +=

1 ans += cnt * lis[k]

[p][q]

temp[p]

[q]= lis[k]

[p-1

][q]

+ lis[k]

[p+1

][q]

+ lis[k]

[p][q-1]

+ lis[k]

[p][q+

1]

k +=

1return ans %(10

**9+7

)

Leetcode 576 出界的路徑數

給定乙個 m n 的網格和乙個球。球的起始座標為 i,j 你可以將球移到相鄰的單元格內,或者往上 下 左 右四個方向上移動使球穿過網格邊界。但是,你最多可以移動 n 次。找出可以將球移出邊界的路徑數量。答案可能非常大,返回 結果 mod 109 7 的值。示例 1 輸入 m 2,n 2,n 2,i ...

Leetcode 576 出界的路勁數

給定乙個m n的網格和乙個球。球的起始座標為 i,j 你可以將球移到相鄰的單元格內,或者往上 下 左 右四個方向上移動使球穿過網格邊界。但是,你最多可以移動n次。找出可以將球移出邊界的路徑數量。答案可能非常大,返回 結果 mod 109 7 的值。示例 1 輸入 m 2,n 2,n 2,i 0,j ...

leetcode演算法題 出界的路徑數

動態規劃 dp i j k 儲存的是在 i,j 這個點,步數為k的所有路徑數狀態轉移 dp i j len dp i 1 j len 1 dp i j 1 len 1 dp i 1 j len 1 dp i j 1 len 1 表示從上下左右四個點走到 i,j 的路徑數 int findpaths ...