大家好,我是 @负雪明烛。👈👈 点击关注,优质题解不间断。
题目大意
有个N * N
的棋盘,上面有个马,马走日字象走田嘛,找出这个马走了K步之后依然在这个棋盘上的概率。
解题方法
动态规划
第一感觉是 dfs,但是 n 和 k 都太大,如果 dfs 的话一定会超时的,所以还是得用 dp 来解。
定义的 **dp[i][j]**
数组代表到了某一轮,马能到 **[i, j]**
这个位置所有可能的次数。
计算思路是:马每次有 8 个移动方向,我们计算这 8 次中里面有多少种可能会落在棋盘上。
dp 更新的策略是,我们遍历棋盘的每个位置,当前的数值是能走到这个位置的在上一轮 dp 的数值 + 1。
循环 K 次以后,把马仍在棋盘上的次数相加(表示马留在棋盘上的所有可能次数之和),除以 $8^K$(马每次有 8 种移动方向), 表示马仍在棋盘上的概率。
注意,python2里面的/默认的是地板除,需要用float再除得到概率。
点击查看【bilibili】
Python 代码如下:
class Solution(object):
def knightProbability(self, N, K, r, c):
"""
:type N: int
:type K: int
:type r: int
:type c: int
:rtype: float
"""
dp = [[0 for i in range(N)] for j in range(N)]
dp[r][c] = 1
directions = [(1, 2), (1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1), (-1, 2), (-1, -2)]
for k in range(K):
new_dp = [[0 for i in range(N)] for j in range(N)]
for i in range(N):
for j in range(N):
for d in directions:
x, y = i + d[0], j + d[1]
if x < 0 or x >= N or y < 0 or y >= N:
continue
new_dp[i][j] += dp[x][y]
dp = new_dp
return sum(map(sum, dp)) / float(8 ** K)
参考资料:
https://www.youtube.com/watch?v=MyJvMydR2G4
- 时间复杂度:$O(K * N ^ 2)$
- 空间复杂度:$O(N ^ 2)$
总结
- 这个题想清楚动态规划的转移方程之后,不难。
- 只用考虑马有多少中可能留在棋盘上就可以。
我是 @负雪明烛 ,刷算法题 1000 多道,写了 1000 多篇算法题解,收获阅读量 300 万。关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。
- 在刷题的时候,如果你不知道该怎么刷题,可以看 LeetCode 应该怎么刷?
- 如果你觉得题目太多,想在短时间内快速提高,可以看 LeetCode 最经典的 100 道题。
- 送你一份刷题的代码模板:【LeetCode】代码模板,刷题必会