题目描述
思路
动态规划
一个骑士有8种可能的走法,骑士会从中以等概率随机选择一种,部分走法可能会让骑士离开棋盘,其他的走法会让骑士移动到棋盘的其他位置,并且剩余的移动次数会减少1。
定义dp[step][i][j]表示骑士从棋盘上的点(i, j)出发,走了step步时仍然留在棋盘上的概率。当(i, j)不在棋盘上时,概率为0;当(i, j)在棋盘上且step=0,概率为1。对于其他情况,
d
p
[
s
t
e
p
]
[
i
]
[
j
]
=
1
8
∗
∑
d
i
,
d
j
d
p
[
s
t
e
p
−
1
]
[
i
+
d
i
]
[
j
+
d
j
]
dp[step][i][j] = \frac{1}{8} * \sum_{di, dj}dp[step-1][i+di][j+dj]
dp[step][i][j]=81∗di,dj∑dp[step−1][i+di][j+dj]
其中(di, dj)为该走法对坐标的偏移量,共有8种。
Python实现
class Solution:
def knightProbability(self, n: int, k: int, row: int, column: int) -> float:
dp = [[[0] * n for i in range(n)] for i in range(k+1)]
for step in range(k+1):
for i in range(n):
for j in range(n):
if step == 0:
dp[step][i][j] = 1
else:
for di, dj in ((-2, -1), (-2, 1), (2, -1), (2, 1), (1, -2), (1, 2), (-1, -2), (-1, 2)):
ni, nj = i+di, j+dj
if 0 <= ni < n and 0 <= nj < n:
dp[step][i][j] += dp[step-1][ni][nj] / 8
return dp[k][row][column]
Java实现
class Solution {
static int[][] dirs = {{-2, -1}, {-2, 1}, {2, -1}, {2, 1}, {-1, -2}, {-1, 2}, {1, -2}, {1, 2}};
public double knightProbability(int n, int k, int row, int column) {
double[][][] dp = new double[k + 1][n][n];
for (int step = 0; step <= k; step++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (step == 0) {
dp[step][i][j] = 1;
} else {
for (int[] dir : dirs) {
int ni = i + dir[0], nj = j + dir[1];
if (ni >= 0 && ni < n && nj >= 0 && nj < n) {
dp[step][i][j] += dp[step - 1][ni][nj] / 8;
}
}
}
}
}
}
return dp[k][row][column];
}
}