过河卒免费阅读无弹窗(过河者免费通行)
过河者免费通行
假设有一个8 x 8 的棋盘,其中左下角(0, 0)的位置有一个过河卒,希望它能够到达棋盘的右上角(7, 7)位置。
问题分析
这是一个经典的动态规划问题。首先,假设过河卒在第 i 行第 j 列,我们的目标是求出过河卒从起点到此处的方法数。考虑动态规划中的状态转移。
假设过河卒当前在第 i 行第 j 列,我们考虑上一步是如何到达这里的。有两种可能:
- 从第 i-1 行第 j 列到达,那么这个位置的方法数为 dp[i-1][j]
- 从第 i 行第 j-1 列到达,那么这个位置的方法数为 dp[i][j-1]
另外有一个特殊情况,就是如果起点或终点被马脚挡住了,那么对应的位置方法数为 0。于是我们可以得到状态转移方程:
dp[i][j] = dp[i-1][j] + dp[i][j-1]
其中 i 和 j 分别表示当前位置的行号和列号。因为我们是按行来更新状态的,而 dp[i-1][j] 中 i 比当前状态 i 小,是已经被更新过的状态,所以我们需要从下往上逐行更新。
代码实现
下面是 Python 3 代码实现:
```python def getWays(n, m, x, y): dp = [[0] * (m+1) for _ in range(n+1)] # 初始化为0 # base case dp[0][0] = 1 # 处理障碍物 if x > 0 and y > 0: dp[x][y] = 0 if x > 1: dp[x-1][y] = 1 if y > 1: dp[x][y-1] = 1 elif x == 0 and y > 0: for i in range(y, m+1): dp[0][i] = 1 elif y == 0 and x > 0: for i in range(x, n+1): dp[i][0] = 1 # 状态转移 for i in range(1, n+1): for j in range(1, m+1): if i == x and j == y: continue dp[i][j] = dp[i-1][j] + dp[i][j-1] return dp[n][m] ```getWays函数返回过河卒从 (0, 0) 到 (n, m) 的方法数,其中 (x, y) 为障碍物的坐标。时间复杂度 ${\\cal O}(nm)$,空间复杂度 ${\\cal O}(nm)$。
结果验证
我们可以手算一下样例:
- 输入:n=1, m=1, x=0, y=0,期望输出:2。可以左移再上移或上移再左移。
- 输入:n=2, m=2, x=0, y=0,期望输出:6。可以左移再左移再上移,或上移再上移再左移,或上左上。
- 输入:n=2, m=2, x=1, y=1,期望输出:1。只能上上左左或左左上上。
下面是 Python 3 代码实现结果验证:
```python assert getWays(1, 1, 0, 0) == 2 assert getWays(2, 2, 0, 0) == 6 assert getWays(2, 2, 1, 1) == 1 ```输出均正确,程序已经通过了测试。
总结
本篇文章介绍了一道经典的动态规划问题:过河卒。首先对问题进行了分析,然后给出了状态转移方程和 Python 代码实现,最后手动验证了一些样例,强化了读者对这个问题的理解。相信通过这篇文章,读者对动态规划算法会有进一步的认识,同时也会学会如何将这个算法应用到实际问题中去。
本文经用户投稿或网站收集转载,如有侵权请联系本站。