题目
- 出界的路径数
难度:简单给你一个大小为
m x n
的网格和一个球。球的起始坐标为[startRow, startColumn]
。你可以将球移到在四个方向上相邻的单元格内(可以穿过网格边界到达网格之外)。你 最多 可以移动maxMove
次球。
给你五个整数 m
、n
、maxMove
、startRow
以及 startColumn
,找出并返回可以将球移出边界的路径数量。因为答案可能非常大,返回对 109 + 7
取余 后的结果。
示例 1:
输入:m = 2, n = 2, maxMove = 2, startRow = 0, startColumn = 0 输出:6
示例 2:
输入:m = 1, n = 3, maxMove = 3, startRow = 0, startColumn = 1 输出:12
提示:
1 <= m, n <= 50
0 <= maxMove <= 50
0 <= startRow < m
0 <= startColumn < n
f方法一: 动态规划
思路
这一题显然是要用动态规划来做。状态也不难写,dp[move][r][c]
表示第move
步走到第r
行第c
列的数量。状态转移方程也不难想到,即dp[move][r][c]
等于move-1
上一步步第r
行第c
列上下左右四个数的和,当然这是要在范围内,这里需要一个判断。而我的代码实现当中,是将这一步第r
行第c
列上下左右四个数加到下一步去。
较为复杂的我认为是在对于边界一圈的情况的考虑。如果球走到边界上了,剩余的步数至少还有一步,那他就可以出界,而且有多少种情况能走到边界的这个位置就有多少种出界的情况。但就如题目中的示例那样,边界的不同位置出界的可能i性是不同的。所以,我是在循环当中,先判断这个位置是不是边界以及是哪一种边界,如果是,再判断这个位置上是不是0,如果不是0,说明可以出界,那就将它加到出界总数去,一种边界加一次,这样就解决了边界不同位置有不同出界的可能性。
代码
1 | def findPaths(m, n, maxMove, startRow, startColumn): |
方法二: 卷积
大佬都在评论区。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18def findPaths(m, n, maxMove, startRow, startColumn):
if maxMove <= 0:
return 0
ans = 0
a = numpy.zeros((m, n), )
a[startRow, startColumn] = 1
b = numpy.zeros((3, 3), int)
b[0][1] = b[1][0] = b[-1][1] = b[1][-1] = 1
# print(a)
for _ in range(maxMove):
ans += (a[:, 0].sum() + a[:, -1].sum() +
a[0, :].sum() + a[-1, :].sum()) % 1_000_000_007
a = scipy.signal.convolve2d(a, b, 'same') % 1_000_000_007
print(a)
return int(ans) % 1_000_000_007