LeetCode 688. “马”在棋盘上的概率

##题目
688. “马”在棋盘上的概率

##内容

已知一个 NxN 的国际象棋棋盘,棋盘的行号和列号都是从 0 开始。即最左上角的格子记为 (0, 0),最右下角的记为 (N-1, N-1)。 
现有一个 “马”(也译作 “骑士”)位于 (r, c) ,并打算进行 K 次移动。 
如下图所示,国际象棋的 “马” 每一步先沿水平或垂直方向移动 2 个格子,然后向与之相垂直的方向再移动 1 个格子,共有 8 个可选的位置。
image.png

现在 “马” 每一步都从可选的位置(包括棋盘外部的)中独立随机地选择一个进行移动,直到移动了 K 次或跳到了棋盘外面。
求移动结束后,“马” 仍留在棋盘上的概率。
示例:
输入: 3, 2, 0, 0
输出: 0.0625
解释:
输入的数据依次为 N, K, r, c
第 1 步时,有且只有 2 种走法令 “马” 可以留在棋盘上(跳到(1,2)或(2,1))。对于以上的两种情况,各自在第2步均有且只有2种走法令 “马” 仍然留在棋盘上。
所以 “马” 在结束后仍在棋盘上的概率为 0.0625。
注意:
N 的取值范围为 [1, 25]
K 的取值范围为 [0, 100]
开始时,“马” 总是位于棋盘上
##题解
dfs搜索 定一个三层dp 通过递归 记录第k次到达当前位置时之后会留在棋牌的走法
最后输出 dp[r][c][k]
##代码

/**
 * @desc
 * @Description Created by chenjian on 2019/9/6.
 */
class lc688 {


    double[][][] dp;

    int[][] dist = {{2, 1}, {-2, 1}, {2, -1}, {-2, -1},
            {1, 2}, {1, -2}, {-1, 2}, {-1, -2}};

    public double knightProbability(int N, int K, int r, int c) {
        if (K == 0) {
            return 1;
        }
        dp = new double[N][N][K + 1];
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                for (int l = 0; l <= K; l++)
                    dp[i][j][l] = -1;

        dfs(r, c, K, N, 0);
        return dp[r][c][K] / Math.pow(8, K);
    }

    private double dfs(int r, int c, int k, int n, int count) {
        if (k - count == -1) {
            if (judge(r, c, n)) {
                return 1;
            }
            return 0;
        }
        if (dp[r][c][k - count] == -1) {
            double sum = 0;
            for (int i = 0; i < 8; i++) {
                if (judge(r + dist[i][0], c + dist[i][1], n)) {
                    sum += dfs(r + dist[i][0], c + dist[i][1], k, n, count + 1);
                }
            }
            dp[r][c][k - count] = sum;
        }
        return dp[r][c][k - count];

    }

    private boolean judge(int r, int c, int n) {
        return r >= 0 && c >= 0 && r < n && c < n;
    }

}

##t提交结果
image.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
运 用 贪 心 算 法 ,vc++ 语 言 编 写 , 可 单 步 输 出 结 果 【问题描述】 跳问题也称骑士遍历、棋盘问题:在8*8方格的棋盘上,从任意指定的方格出发,为象棋中的寻找一条走遍棋盘每一格并且只经过一次的一条路径。 考虑国际象棋棋盘上某个位置的一只,它是否可能只走63步,正好走过除起点外的其他63个位置各一次?如果有一种这样的走法,则称所走的这条路线为一条的周游路线。试设计一个算法找出这样一条的周游路线。 在一个8×8的方格棋盘中,按照国际象棋中的行走规则从棋盘上的某一方格出发,开始在棋盘上周游,如果能不重复地走遍棋盘上的每一个方格, 这样的一条周游路线在数学上被称为国际象棋盘的哈密尔顿链。请你设计一个程序,从键盘输入一个起始方格的坐标,由计算机自动寻找并打印 【算法描述】 本题有较多方法求解,在此仅对回溯法进行分析。 一只棋盘的某一点,它可以朝8个方向前进,方向向量分别是:(2,1)、(2,-1)、(1,2)、(1,-2)、(-2,1)、(-2,-1)、(-1,2)、(-1,-2)。从中任选择一个方向前进,到达新的位置。在从新的位置选择一个方向前进,继续,直到无法前进为止。无法前进可能有如下原因:下一位置超出边界、下一位置已经被访问过。当已经无法前进时,就回退到上一位置,从新选择一个新的方向前进;如果还是无法前进,就再回退到上一位置……
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值