解题思路
本题是一道经典动态规划
题
- 设计状态:
当前步长为step
,当前坐标为x
,y
,值为当前留在棋盘上的概率
- 写出状态转移方程
d p [ s t e p ] [ x ] [ y ] + = 1 8 ∗ ∑ i = 0 8 d p [ s t e p − 1 ] [ x + d i r [ i ] [ 0 ] ] [ y + d [ i ] [ 1 ] ] dp[step][x][y]+=\frac{1}{8}\ast\sum_{i=0}^8 dp[step-1][x+dir[i][0]][y+d[i][1]] dp[step][x][y]+=81∗i=0∑8dp[step−1][x+dir[i][0]][y+d[i][1]]
这里的dir指的是方向数组,用于描述每一个方向,一共有八个方向 - 设置初始状态
这里的初始状态是step=0
的状态,该状态意思是骑士停在了该位置,不用再往下走了,也就是骑士的最终位置,并且这个最终位置在棋盘上
,此时将该状态的所有值设置为1
,意思是骑士走完了所有步数
并且留在棋盘
上坐标为x,y
的概率为100%
。
(没有状态能转移到(step=0)上,如果骑士能走-1步的话,那么step=0就不是初始状态)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
dp[0][i][j]=1;
}
- 开始状态转移
for (int step = 1; step <= k; step++)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
for (int dir = 0; dir < 8; dir++)
{
int nx = i + dirs[dir][0], ny = j + dirs[dir][1];
if (nx < n && nx >= 0 && ny < n && ny >= 0)
dp[step][i][j] += dp[step - 1][nx][ny] / 8;
}
}
}
}
完整代码:
class Solution
{
public:
vector<vector<int>> dirs = {{-2, -1}, {-2, 1}, {2, -1}, {2, 1}, {-1, 2}, {1, 2}, {1, -2}, {-1, -2}};
double knightProbability(int n, int k, int row, int column)
{
vector<vector<vector<double>>> dp(k + 1, vector<vector<double>>(
n, vector<double>(n)));
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
dp[0][i][j] = 1;
}
for (int step = 1; step <= k; step++)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
for (int dir = 0; dir < 8; dir++)
{
int nx = i + dirs[dir][0], ny = j + dirs[dir][1];
if (nx < n && nx >= 0 && ny < n && ny >= 0)
dp[step][i][j] += dp[step - 1][nx][ny] / 8;
}
}
}
}
return dp[k][row][column];
}
};