轉自:https://mp.weixin.qq.com/s/bHpN9gB8-_zPJ-_YZQGMKg
題意
一個機器人目前停留在一個 m x n 的表格的左上角(如下圖所示,標註爲'Start'). 這個機器人只能向下或者向右移動.機器人的目標是盡力到達表格的右下角(下圖標註爲'Finish'). 求:一共有多少條不同的路徑可以實現機器人的目的. 注意:m 和 n 均不超過 100.
題解
算法及複雜度(0 ms) 分析題目發現,到達一個點的方法只能是從這個點的上方或者左方.所以問題的解可以嘗試通過左邊的點的解和上邊的解的結合得到. 如何結合得到?如果從開始到達(i, j)這個點的上方點(i - 1, j)的路徑數爲m, 從開始到達(i,j)點的左方點(i, j - 1)的路徑數爲n,顯然可以得到到達(i, j)的路徑數就是 m + n.也就是到達上方點的路徑數加上到達左方點的路徑數. 由於到達每個左邊都有一個路徑數,不妨設開始點到達(i, j)點的路徑數爲dpi. 那麼,根據上邊的分析有開始點到達(i, j)點的路徑數爲dp[i][j] = dp[i - 1][j] + dp[i][j - 1].這個方程是顯然成立的. 時間複雜度: O(mn),表格中每個位置進行一次計算即可. 代碼參見本文件夾下solution.cpp
算法正確性
正確性證明 以上做法使用的動態規劃的思想,下面證明一下本題可以使用動態規劃的思想. 一個問題要想使用動態規劃進行求解,就需要滿足兩個條件:(1)具有最優子結構(2)無後效性. 在本題中,從開始點到達某點的路徑數可以看做是從開始點到達某點最多的路徑數.如果求從開始點到達某點最多的路徑數,需要要求已知開始點到達它上方點的最多路徑數和開始點到達它下方點的最多路徑數,以此進行轉移.因此滿足條件(1);對於條件(2),表明當前決策,也就是dp[i][j] = dp[i - 1][j] + dp[i][j - 1]是不需要通過後邊的狀態得到的或者說不受後邊狀態(比如dpi + 1)的影響,顯然是滿足的. 所以本題可以根據上述狀態轉移方程進行求解.
import numpy as np;
def vlCal(m,n):
#初始化
dp = np.zeros([m,n], dtype = int)
dp[0][1:n] = 1
dp[1:m,0] = 1
dp[1][1] = 2
#求解過程
for imm in range(1,m):
for inn in range(1,n):
if (imm==3) :
print("hello")
dp[imm][inn]=dp[imm-1][inn]+dp[imm][inn-1]
return dp[m-1][n-1]
print(vlCal(3,4))