原文:

给定 nxn 棋盘和位置(x,y)的骑士。骑士必须精确地走 k 步,在每一步中,他均匀地随机选择 8 个方向中的任何一个。骑士走完 k 步后留在棋盘上的概率是多少,条件是一旦离开就不能再进入棋盘? 例:

let's take:
8x8 chessboard,
initial position of the knight : (0, 0),
number of steps : 1
at each step, the knight has 8 different positions to choose from. 
if it starts from (0, 0), after taking one step it will lie inside the
board only at 2 out of 8 positions, and will lie outside at other positions.
so, the probability is 2/8 = 0.25

进场:

我们可以观察到的一件事是,在每一步,骑士都有 8 个选择。假设,骑士必须走 k 步,在走完第 k 步后,骑士到达(x,y)。从 knight 可以一步到达(x,y)的位置有 8 个不同的位置,分别是:(x 1,y 2),(x 2,y 1),(x 2,y-1),(x 1,y-2),(x-1,y-2),(x-2,y-1),(x-2,y-1),(x-2,y 1),(x-1,y 2)。 如果我们已经知道 k-1 步后到达这 8 个位置的概率会怎样?

那么,k 步之后的最终概率将简单地等于(k-1 步之后到达这 8 个位置中每一个的σ概率)/8;

这里我们除以 8,因为这 8 个位置中的每一个都有 8 个选择,位置(x,y)是其中一个选择。

对于位于板外的位置,我们要么将它们的概率取为 0,要么干脆忽略它。

因为我们需要跟踪每一步的每个位置的概率,所以我们需要动态规划来解决这个问题。 我们将取一个数组 dp[x][y][steps],它将存储在(steps)次移动后达到(x,y)的概率。

基本情况:如果步数为 0,那么骑士留在棋盘内的概率为 1。 下面是上述方法的实现:

c

// c   program to find the probability of the
// knight to remain inside the chessboard after
// taking exactly k number of steps
#include 
using namespace std;
// size of the chessboard
#define n 8
// direction vector for the knight
int dx[] = { 1, 2, 2, 1, -1, -2, -2, -1 };
int dy[] = { 2, 1, -1, -2, -2, -1, 1, 2 };
// returns true if the knight is inside the chessboard
bool inside(int x, int y)
{
    return (x >= 0 and x < n and y >= 0 and y < n);
}
// bottom up approach for finding the probability to
// go out of chessboard.
double findprob(int start_x, int start_y, int steps)
{
    // dp array
    double dp1[n][n][steps   1];
    // for 0 number of steps, each position
    // will have probability 1
    for (int i = 0; i < n;   i)
        for (int j = 0; j < n;   j)
            dp1[i][j][0] = 1;
    // for every number of steps s
    for (int s = 1; s <= steps;   s) {
        // for every position (x,y) after
        // s number of steps
        for (int x = 0; x < n;   x) {
            for (int y = 0; y < n;   y) {
                double prob = 0.0;
                // for every position reachable from (x,y)
                for (int i = 0; i < 8;   i) {
                    int nx = x   dx[i];
                    int ny = y   dy[i];
                    // if this position lie inside the board
                    if (inside(nx, ny))
                        prob  = dp1[nx][ny][s - 1] / 8.0;
                }
                // store the result
                dp1[x][y][s] = prob;
            }
        }
    }
    // return the result
    return dp1[start_x][start_y][steps];
}
// driver code
int main()
{
    // number of steps
    int k = 3;
    // function call
    cout << findprob(0, 0, k) << endl;
    return 0;
}

java 语言(一种计算机语言,尤用于创建网站)

// java program to find the probability
// of the knight to remain inside the
// chessboard after taking exactly k
// number of steps
class gfg {
    // size of the chessboard
    static final int n = 8;
    // direction vector for the knight
    static int dx[] = { 1, 2, 2, 1, -1, -2, -2, -1 };
    static int dy[] = { 2, 1, -1, -2, -2, -1, 1, 2 };
    // returns true if the knight is
    // inside the chessboard
    static boolean inside(int x, int y)
    {
        return (x >= 0 && x < n && y >= 0 && y < n);
    }
    // bottom up approach for finding
    // the probability to go out of
    // chessboard.
    static double findprob(int start_x, int start_y,
                           int steps)
    {
        // dp array
        double dp1[][][] = new double[n][n][steps   1];
        // for 0 number of steps, each position
        // will have probability 1
        for (int i = 0; i < n;   i)
            for (int j = 0; j < n;   j)
                dp1[i][j][0] = 1;
        // for every number of steps s
        for (int s = 1; s <= steps;   s) {
            // for every position (x, y) after
            // s number of steps
            for (int x = 0; x < n;   x) {
                for (int y = 0; y < n;   y) {
                    double prob = 0.0;
                    // for every position reachable
                    // from (x, y)
                    for (int i = 0; i < 8;   i) {
                        int nx = x   dx[i];
                        int ny = y   dy[i];
                        // if this position lie
                        // inside the board
                        if (inside(nx, ny))
                            prob
                                 = dp1[nx][ny][s - 1] / 8.0;
                    }
                    // store the result
                    dp1[x][y][s] = prob;
                }
            }
        }
        // return the result
        return dp1[start_x][start_y][steps];
    }
    // driver code
    public static void main(string[] args)
    {
        // number of steps
        int k = 3;
        // function call
        system.out.println(findprob(0, 0, k));
    }
}
// this code is contributed by anant agarwal.

python 3

# python3 program to find the probability of
# the knight to remain inside the chessboard
# after taking exactly k number of steps
# size of the chessboard
n = 8
# direction vector for the knight
dx = [1, 2, 2, 1, -1, -2, -2, -1]
dy = [2, 1, -1, -2, -2, -1, 1, 2]
# returns true if the knight
# is inside the chessboard
def inside(x, y):
    return (x >= 0 and x < n and y >= 0 and y < n)
# bottom up approach for finding the
# probability to go out of chessboard.
def findprob(start_x, start_y, steps):
    # dp array
    dp1 = [[[0 for i in range(n 5)]
            for j in range(n 5)]
            for k in range(steps   5)]
    # for 0 number of steps, each
    # position will have probability 1
    for i in range(n):
        for j in range(n):
            dp1[i][j][0] = 1
    # for every number of steps s
    for s in range(1, steps   1):
        # for every position (x,y) after
        # s number of steps
        for x in range(n):
            for y in range(n):
                prob = 0.0
                # for every position reachable from (x,y)
                for i in range(8):
                    nx = x   dx[i]
                    ny = y   dy[i]
                    # if this position lie inside the board
                    if (inside(nx, ny)):
                        prob  = dp1[nx][ny][s-1] / 8.0
                # store the result
                dp1[x][y][s] = prob
    # return the result
    return dp1[start_x][start_y][steps]
# driver code
# number of steps
k = 3
# function call
print(findprob(0, 0, k))
# this code is contributed by anant agarwal.

c

// c# program to find the
// probability of the knight
// to remain inside the
// chessboard after taking
// exactly k number of steps
using system;
class gfg {
    // size of the chessboard
    static int n = 8;
    // direction vector
    // for the knight
    static int[] dx = { 1, 2, 2, 1, -1, -2, -2, -1 };
    static int[] dy = { 2, 1, -1, -2, -2, -1, 1, 2 };
    // returns true if the
    // knight is inside the
    // chessboard
    static bool inside(int x, int y)
    {
        return (x >= 0 && x < n && y >= 0 && y < n);
    }
    // bottom up approach for
    // finding the probability
    // to go out of chessboard.
    static double findprob(int start_x, int start_y,
                           int steps)
    {
        // dp array
        double[, , ] dp1 = new double[n, n, steps 1];
        // for 0 number of steps,
        // each position will have
        // probability 1
        for (int i = 0; i < n;   i)
            for (int j = 0; j < n;   j)
                dp1[i, j, 0] = 1;
        // for every number
        // of steps s
        for (int s = 1; s <= steps;   s) {
            // for every position (x, y)
            // after s number of steps
            for (int x = 0; x < n;   x) {
                for (int y = 0; y < n;   y) {
                    double prob = 0.0;
                    // for every position
                    // reachable from (x, y)
                    for (int i = 0; i < 8;   i) {
                        int nx = x   dx[i];
                        int ny = y   dy[i];
                        // if this position lie
                        // inside the board
                        if (inside(nx, ny))
                            prob
                                 = dp1[nx, ny, s - 1] / 8.0;
                    }
                    // store the result
                    dp1[x, y, s] = prob;
                }
            }
        }
        // return the result
        return dp1[start_x, start_y, steps];
    }
    // driver code
    static void main()
    {
        // number of steps
        int k = 3;
        // function call
        console.writeline(findprob(0, 0, k));
    }
}
// this code is contributed
// by sam007

服务器端编程语言(professional hypertext preprocessor 的缩写)

= 0 and $x < $n and
            $y >= 0 and $y < $n);
}
// bottom up approach for finding the
// probability to go out of chessboard.
function findprob($start_x, $start_y, $steps)
{
    global $n, $dx, $dy;
    // dp array
    $dp1 = array_fill(0, $n,
           array_fill(0, $n,
           array_fill(0, $steps 1, null)));
    // for 0 number of steps, each
    // position will have probability 1
    for ($i = 0; $i < $n;   $i)
        for ($j = 0; $j < $n;   $j)
            $dp1[$i][$j][0] = 1;
    // for every number of steps s
    for ($s = 1; $s <= $steps;   $s)
    {
        // for every position (x,y) after
        // s number of steps
        for ($x = 0; $x < $n;   $x)
        {
            for ($y = 0; $y < $n;   $y)
            {
                $prob = 0.0;
                // for every position
                // reachable from (x,y)
                for ($i = 0; $i < 8;   $i)
                {
                    $nx = $x   $dx[$i];
                    $ny = $y   $dy[$i];
                    // if this position lie inside
                    // the board
                    if (inside($nx, $ny))
                        $prob  = $dp1[$nx][$ny][$s - 1] / 8.0;
                }
                // store the result
                $dp1[$x][$y][$s] = $prob;
            }
        }
    }
    // return the result
    return $dp1[$start_x][$start_y][$steps];
}
// driver code
// number of steps
$k = 3;
// function call
echo findprob(0, 0, $k) . "\n";
// this code is contributed by ita_c
?>

java 描述语言


output

0.125

时间复杂度 : o(nxnxkx8)也就是 o(nxnxk),其中 n 是板子的大小,k 是步数。 空间复杂度 : o(nxnxk)

本文由阿维纳什库马尔锯供稿。如果你喜欢 geeksforgeeks 并想投稿,你也可以使用写一篇文章或者把你的文章邮寄到 contribute@geeksforgeeks.org。看到你的文章出现在极客博客pg电子试玩链接主页上,帮助其他极客。 如果你发现任何不正确的地方,或者你想分享更多关于上面讨论的话题的信息,请写评论。