[LeetCode] Knight Probability in Chessboard 棋盘上骑士的可能性

简介:

On an NxN chessboard, a knight starts at the r-th row and c-th column and attempts to make exactly K moves. The rows and columns are 0 indexed, so the top-left square is (0, 0), and the bottom-right square is (N-1, N-1).

A chess knight has 8 possible moves it can make, as illustrated below. Each move is two squares in a cardinal direction, then one square in an orthogonal direction.

Each time the knight is to move, it chooses one of eight possible moves uniformly at random (even if the piece would go off the chessboard) and moves there.

The knight continues moving until it has made exactly K moves or has moved off the chessboard. Return the probability that the knight remains on the board after it has stopped moving.

Example:

Input: 3, 2, 0, 0
Output: 0.0625
Explanation: There are two moves (to (1,2), (2,1)) that will keep the knight on the board.
From each of those positions, there are also two moves that will keep the knight on the board.
The total probability the knight stays on the board is 0.0625.

Note:

  • N will be between 1 and 25.
  • K will be between 0 and 100.
  • The knight always initially starts on the board.

这道题给了我们一个大小为NxN国际象棋棋盘,上面有个骑士,相当于我们中国象棋中的马,能走‘日’字,给了我们一个起始位置,然后说允许我们走K步,问走完K步之后还能留在棋盘上的概率是多少。那么要求概率,我们必须要先分别求出分子和分母,其中分子是走完K步还在棋盘上的走法,分母是没有限制条件的总共的走法。那么分母最好算,每步走有8种跳法,那么K步就是8的K次方种了。关键是要求出分子,博主开始向的方法是以给定位置为起始点,然后进行BFS,每步遍历8种情况,遇到在棋盘上的就计数器加1,结果TLE了。上论坛看大家的解法,结果发现都是换了一个角度来解决问题的,并不很关心骑士的起始位置,而是把棋盘上所有位置上经过K步还留在棋盘上的走法总和都算出来,那么最后直接返回需要的值即可。跟之前那道Out of Boundary Paths没啥本质上的区别,又是换了一个马甲就不会了系列。还是要用DP来做,我们可以用三维DP数组,也可以用二维DP数组来做,这里为了省空间,我们就用二维DP数组来做,其中dp[i][j]表示在棋盘(i, j)位置上走完当前步骤还留在棋盘上的走法总和,初始化为1,我们其实将步骤这个维度当成了时间维度在不停更新。好,下面我们先写出8种‘日’字走法的位置的坐标,就像之前遍历迷宫上下左右四个方向坐标一样,这不过这次位置变了而已。然后我们一步一步来遍历,每一步都需要完整遍历一遍棋盘的每个位置,新建一个临时数组t,大小和dp数组相同,但是初始化为0,然后对于遍历到的棋盘上的每一个格子,我们都遍历8中解法,如果新的位置不在棋盘上了,直接跳过,否则就加上上一步中的dp数组中对应的值,遍历完棋盘后,将dp数组更新为这个临时数组t,参见代码如下: 

解法一:

public:
    double knightProbability(int N, int K, int r, int c) {
        if (K == 0) return 1;
        vector<vector<double>> dp(N, vector<double>(N, 1));
        vector<vector<int>> dirs{{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};
        for (int m = 0; m < K; ++m) {
            vector<vector<double>> t(N, vector<double>(N, 0));
            for (int i = 0; i < N; ++i) {
                for (int j = 0; j < N; ++j) {
                    for (auto dir : dirs) {
                        int x = i + dir[0], y = j + dir[1];
                        if (x < 0 || x >= N || y < 0 || y >= N) continue;
                        t[i][j] += dp[x][y];
                    }
                }
            }
            dp = t;
        }
        return dp[r][c] / pow(8, K);
    }
};

解法二:

public:
    vector<vector<int>> dirs{{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}};
    double knightProbability(int N, int K, int r, int c) {
        vector<vector<vector<double>>> memo(K + 1, vector<vector<double>>(N, vector<double>(N, 0.0)));
        return helper(memo, N, K, r, c) / pow(8, K);
    }
    double helper(vector<vector<vector<double>>>& memo, int N, int k, int r, int c) {
        if (k == 0) return 1.0;
        if (memo[k][r][c] != 0.0) return memo[k][r][c];
        for (auto dir : dirs) {
            int x = r + dir[0], y = c + dir[1];
            if (x < 0 || x >= N || y < 0 || y >= N) continue;
            memo[k][r][c] += helper(memo, N, k - 1, x, y);
        }
        return memo[k][r][c];
    }
};

参考资料:

https://discuss.leetcode.com/topic/105571/my-accepted-dp-solution

https://discuss.leetcode.com/topic/105597/c-java-dp-concise-solution

本文转自博客园Grandyang的博客,原文链接:[LeetCode] Knight Probability in Chessboard 棋盘上骑士的可能性

,如需转载请自行联系原博主。

相关文章
|
2月前
|
算法 数据可视化 API
常用的Python第三方库中哪个库可以用于图像处理?
常用的Python第三方库中哪个库可以用于图像处理?
197 5
|
2月前
|
供应链 JavaScript 数据挖掘
一套SaaS ERP管理系统源码,生产管理系统源代码
小微企业SaaS ERP系统,基于SpringBoot+Vue+UniAPP开发,集成进销存、采购销售、MRP生产、财务、CRM、OA等全流程管理功能,支持自定义表单与工作流,助力企业数字化转型。
174 1
|
弹性计算 安全 Java
使用 OSS 的 bucket 进行文件上传下载|学习笔记
快速学习使用 OSS 的 bucket 进行文件上传下载
1553 0
|
7月前
|
人工智能 移动开发 监控
「10秒发现,5分钟定位」- 阿里云EMAS应用监控引领全链路智能监控新时代
阿里云 EMAS 应用监控是面向客户端的全方位监控服务平台,覆盖移动端和Web/H5端。基于阿里巴巴深厚的技术沉淀,提供稳定高效的监控服务,帮助开发者实时掌握应用性能与稳定性情况,快速构建“感知 > 定位 > 修复”运维闭环,保障应用质量,优化用户体验。
391 13
「10秒发现,5分钟定位」- 阿里云EMAS应用监控引领全链路智能监控新时代
|
7月前
|
JSON 监控 API
深度解析淘宝天猫店铺所有商品API接口,一文带你吃透
本文介绍如何通过淘宝开放平台的API获取店铺所有商品信息,适用于电商数据分析、竞品监控等场景。核心接口为`tb.items.onsale.get`(出售中商品)和`tb.items.inventory.get`(库存商品列表)。接口采用HTTP POST请求,返回JSON格式数据,包含商品总数、列表及各商品的ID、标题、价格、图片URL等关键信息,并提供Python实现示例,助力开发者高效获取与处理数据。
|
SQL 关系型数据库 MySQL
MySQL:Access denied for user &#39;root&#39;@&#39;localhost&#39;
mysql数据库对权限校验也是特别的严格的,毕竟数据安全是很重要的,那么,像我这种小白用户就会遇到很多像权限不足,或者无法连接数据库的尴尬境遇,那么,假如遇到题中所述的问题如何解决呢?下面请看小白的解决方案!
1563 0
|
vr&ar 图形学 数据安全/隐私保护
2023年13个面向初学者最佳免费3D建模软件
现在有数百种不同的免费 3D 建模软件工具供希望创建自己的 3D 模型的用户使用——因此知道从哪里开始可能会很棘手。 3D 软件建模工具的范围从即使是最新的初学者也易于使用到可能需要数年才能学习的专业级软件——因此选择与您的技能水平相匹配的工具非常重要。
2467 0
|
Linux Python Windows
如何 python import h5py 报错 :/defs.cpython-37m-x86_64-linux-gnu.so: undefined symbol: H5Pset_fapl_ros3
如何 python import h5py 报错 :/defs.cpython-37m-x86_64-linux-gnu.so: undefined symbol: H5Pset_fapl_ros3
如何 python import h5py 报错 :/defs.cpython-37m-x86_64-linux-gnu.so: undefined symbol: H5Pset_fapl_ros3
|
JSON NoSQL 安全
漏洞赏金猎人笔记-使用自动化工具搭建攻击面监控平台的一般性思路
前言 本文是一篇笔记,原文作者是@pry0cc(已经50多岁了),本文内容主要是对原文相关内容做的笔记,出于易读性考虑,对部分字句有所删改。
667 0
漏洞赏金猎人笔记-使用自动化工具搭建攻击面监控平台的一般性思路
|
并行计算 搜索推荐 算法