題目
一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記爲“Start” )。
機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記爲“Finish”)。
問總共有多少條不同的路徑?(從坐上角走到右下角)
例如,上圖是一個7 x 3 的網格。有多少可能的路徑?
說明:m 和 n 的值均不超過 100。
示例 1:
輸入: m = 3, n = 2
輸出: 3
解釋:
從左上角開始,總共有 3 條路徑可以到達右下角。
1. 向右 -> 向右 -> 向下
2. 向右 -> 向下 -> 向右
3. 向下 -> 向右 -> 向右
示例 2:
輸入: m = 7, n = 3
輸出: 28
題解
這道題拿到題目我覺得大家的第一反應都是這應該是遞歸的題目,因爲我們可以轉化爲子問題,但是這樣暴力肯定會超時,就不用嘗試了。其實在該題遞歸的方法就是從上面到下面不斷的去嘗試,如果我們能記住之前的結果,就對我們下一步有幫助,所以想到了DP的方法。
那麼需要我們遵循DP求解的步驟:
1).定義一個能夠清楚描述最優子問題的數組(明確數組描述的含義)。
2).找出數組元素之間的關係式(狀態轉移方程)
3).找出初始值
格子中的數字代表當前的方法.
1.定義dp[i][j] 代表 當前位置(i,j)有多少種方式能夠走到這個位置
2.我們知道dp[i][j]由 dp[i-1][j]或者dp[i][j-1]轉移過來 由此我們可以得到狀態轉移方程: dp[i][j] = dp[i][j-1] + dp[i-1][j];
3.初始化
- 當前這個狀態只和左邊和上邊的格子有關係,並且依次求解:
優化
上面我們在求解的時候,發現並不需要保存整個矩陣的狀態,只需要當前行和當前列即可,同時又可以進一步優化,當前行我們可以使用外層循環的方式,狀態累加到dp[j]上 ,於是狀態轉移方程編程:
res[j] = res[j] + res[j-1]
dp[1] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dp[j] += dp[j - 1];
}
}
return dp[m];