走方格(递归、动态规划)

1. 问题描述:

在平面上有一些二维的点阵。这些点的编号就像二维数组的编号一样,从上到下依次为第 1 至第 n 行,从左到右依次为第 1 至第 m 列,每一个点可以用行号和列号来表示。现在有个人站在第 1 行第 1 列,要走到第 n 行第 m 列。只能向右或者向下走。注意,如果行号和列数都是偶数,不能走入这一格中。问有多少种方案。

2. 思路分析:

① 其实这道题目与之前的走方格的题目是一样的,只是这里添加了一个限制条件就是不能够走进行数与列数都为偶数的位置,所以添加一个if判断的限制条件即可,第一种比较容易想到的方法是使用递归来解决,因为走格子其实就是一种尝试的过程,我们可以写一个有返回值的递归,当返回当前位置的格子的时候表示的意思是当前格子往下走有多少种走法,并且我们可以知道存在两个平行状态,一个是往下走,一个是往右走,所以这个格子走到终点的方案最终是往下走与往右走的总和,对于方格中的每一个格子都是这样的,所以在层层返回的时候会最终返回到第一个位置得到最终的答案

② 除了使用递归来解决的方法之外,我们还可以使用动态规划的解法,我们知道到达当前格子的走法是由上一个格子与左边的格子走法的总和,所以我们在一开始的时候就初始化第一行与第一列使其为1,然后依次得到每一行中对应位置的走法,其实这个思路还是比较好理解的,并且耗时很小,推荐使用这种做做法来解决

3. 代码如下:

递归:

def solve(x, y, m, n):
    res = 0
    if x == m and y == n: return 1
    if x + 1 <= m and ((x + 1) % 2 != 0 or y % 2 != 0):
        res += solve(x + 1, y, m, n)
    if y + 1 <= n and ((y + 1) % 2 != 0 or x % 2 != 0):
        res += solve(x, y + 1, m, n)
    return res


if __name__ == '__main__':
    print(solve(1, 1, 3, 4))
    print(solve(1, 1, 2, 2))
    print(solve(1, 1, 20, 21))

动态规划:

def solve(n, m):
    # 声明一个m行n列的列表
    grid = [[0] * m for i in range(n)]
    # 将第一列的元素置为0
    for i in range(n):
        grid[i][0] = 1
    for i in range(m):
        grid[0][i] = 1
    for i in range(1, n):
        for j in range(1, m):
            # 行与列都是偶数的情况
            if i % 2 == 1 and j % 2 == 1:
                continue
            grid[i][j] = grid[i - 1][j] + grid[i][j - 1]
    return grid[n - 1][m - 1]


if __name__ == '__main__':
    print(solve(3, 4))
    print(solve(6, 6))
    print(solve(20, 21))

猜你喜欢

转载自blog.csdn.net/qq_39445165/article/details/107331757