执行结果:通过
执行用时和内存消耗如下:
代码如下:
static int dirs[8][2] = {{-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){double dp[200][30][30];memset(dp, 0, sizeof(dp));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.0;} else {for (int k = 0; k < 8; k++) {int ni = i + dirs[k][0], nj = j + dirs[k][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];
}
解题思路:
- 定义方向数组:
static int dirs[8][2] = {{-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)
- 这个函数接受四个参数:棋盘的大小
n
(假设棋盘是n x n
的正方形),步数k
,以及初始位置(row, column)
。
- 动态规划数组初始化:
double dp[200][30][30];
memset(dp, 0, sizeof(dp));
- 定义一个三维动态规划数组
dp
来存储每一步从每一个位置移动到其他位置的概率。数组的大小是根据题目限制预设的(假设棋盘大小不超过200x200)。
- 初始化基础情况:
- 当
step == 0
时,即骑士没有移动,位于初始位置(i, j)
的概率是1.0。 dp[step][i][j] = 1.0;
- 当
- 状态转移:
- 对于每一步
step
(从1到k
),遍历棋盘上的每一个位置(i, j)
。 - 对于每一个位置,计算从上一个步数
step-1
的八个可能的前一个位置(ni, nj)
移动到当前位置(i, j)
的概率。 - 由于骑士每步有八个等可能的移动方向,所以每个前一个位置
(ni, nj)
对当前位置(i, j)
的贡献是dp[step - 1][ni][nj] / 8
。 - 只有在
(ni, nj)
是有效位置(即在棋盘范围内)时,才计算这个贡献。
- 对于每一步
- 返回结果:
- 最后返回
dp[k][row][column]
,即经过k
步后,骑士位于(row, column)
位置的概率。
- 最后返回
总结来说,这段代码通过动态规划的方式,计算了骑士在给定步数内从初始位置移动到目标位置的概率。每一步都考虑了骑士从上一个位置通过八个方向移动到当前位置的所有可能性,并将这些可能性累加起来,最终得到目标位置的概率。