Leetcode 688: 骑士在棋盘上的概率

Definition:

思路

由于刷题尹始对DP和DFS之类的问题还没有什么概念,看到题目第一想法就是直接正向求解,在使用递归实现基本问题的求解之后发现对于k较大的情形递归的方法就失效了,直接超时。后来在评论里面也看到不少老哥用递归超时的,其实思路很简单,但是就是无法AC。
对于每一个起始位置,我们可以通过计算在下一步有多少种可能的走法,找出下一步所有可能的位置以及对应的概率之后,不断向后迭代,最终只留下了能够不离开棋盘的所有步数对应的概率,求和即可得到最终的结果,代码如下

class Solution:def possible_position(self, n: int, row: int, col:int):positions = []if row - 2 >= 0:if col - 1 >= 0:positions.append((row - 2, col - 1))if col + 1 < n:positions.append((row - 2, col + 1))if row - 1 >= 0:if col - 2 >= 0:positions.append((row - 1, col - 2))if col + 2 < n:positions.append((row - 1, col + 2))if row + 1 < n:if col - 2 >= 0:positions.append((row + 1, col - 2))if col + 2 < n:positions.append((row + 1, col + 2))if row + 2 < n:if col - 1 >= 0:positions.append((row + 2, col - 1))if col + 1 < n:positions.append((row + 2, col + 1))return positionsdef knightProbability(self, n: int, k: int, row: int, column: int) -> float:possible_pos = self.possible_position(n, row, column)possibility = len(possible_pos) / 8if k == 0 and (0 <= row < n) and (0 <= column < n):return 1if k == 1:return possibilitycandidates = []for pos in possible_pos:if not ((0 <= row < n) or (0 <= column < n)):continuecandidates.append(possibility * (1 / len(possible_pos)) * self.knightProbability(n, k - 1, pos[0], pos[1]))return sum(candidates)

以上是使用递归进行求解的代码实现,该方法在实际运行时存在超时的问题。在阅读官方题解之后,了解了什么是动态规划并对官方给出的代码进行了理解,下面是其给出的解题方法:

class Solution:def knightProbability(self, n: int, k: int, row: int, column: int) -> float:dp = [[[0] * n for _ in range(n)] for _ in range(k + 1)]for step in range(k + 1):for i in range(n):for j in range(n):if step == 0:dp[step][i][j] = 1else:for di, dj in ((-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)):ni, nj = i + di, j + djif 0 <= ni < n and 0 <= nj < n:dp[step][i][j] += dp[step - 1][ni][nj] / 8return dp[k][row][column]

可以看到,使用动态规划的方法思路非常简洁。使用一个三维数组,第一个维度是channel(也就是step)维度,另外两个维度对应棋盘的行和列。这里其实使用了逆向思维,因为正向推理的过程中可能性非常多,但是反过来考虑的话,如果到了最后一步(k=0)骑士仍旧在棋盘上(此时概率为1,因为没有了后续步骤,骑士已经固定在棋盘上),那么就可以推理在k=1时其在棋盘上的可能位置并计算在对应位置的概率(例如在k=0时骑士在棋盘上的 ( r o w , c o l u m n ) (row,column) (row,column)位置,那么在上一步中其可能存在的位置是可以计算的,即 d p [ s t e p − 1 ] [ r o w + d i ] [ c o l u m n + d j ] dp[step - 1][row + di][column + dj] dp[step−1][row+di][column+dj]),通过反向求解概率直到求得step=k时,便可获得最终结果。

题后反思

本题在题目设置上的技巧在于棋盘格的大小n是固定的,这也就决定了在使用动态规划时状态变量的个数是固定的,因此通过这种反向求解的思路效率较高。值得一提 的是,由于当前的状态仅仅与上一步状态有关,因此状态数组的实际大小可以设置为size = (2, n, n) 通过滚动迭代的方式进一步节省空间开销。

Knight On the Chessboard相关推荐

  1. Knight Probability in Chessboard

    Knight Probability in Chessboard 题目描述:在NxN的棋盘上,骑士走"日"字,经过K次行走之后,骑士还留在棋盘上的概率是多少? 骑士在棋盘上行走时, ...

  2. LWC 52:688. Knight Probability in Chessboard

    LWC 52:688. Knight Probability in Chessboard 传送门:688. Knight Probability in Chessboard Problem: On a ...

  3. Leetcode 688.Knight Probability in Chessboard

    Leetcode 688.Knight Probability in Chessboard 题目: On an NxN chessboard, a knight starts at the r-th ...

  4. leetcode 688. Knight Probability in Chessboard | 688. “马”在棋盘上的概率(dp,记忆化搜索)

    题目 https://leetcode.com/problems/knight-probability-in-chessboard/ 题解 左神讲过类似问题: 给定5个参数,N,M,row,col,k ...

  5. A Knight‘s Journey(POJ-2488)

    A Knight's Journey 题目 题目大意 题目思路 代码 题目 Description Background The knight is getting bored of seeing t ...

  6. 【LeetCode】935. Knight Dialer 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划TLE 空间换时间,利用对称性 优化空间复杂 ...

  7. DFS(二):骑士游历问题

    在国际象棋的棋盘(8行×8列)上放置一个马,按照"马走日字"的规则,马要遍历棋盘,即到达棋盘上的每一格,并且每格只到达一次.例如,下图给出了骑士从坐标(1,5)出发,游历棋盘的一种 ...

  8. POJ-2488 A Knights Journey-深度优先搜索DFS

    POJ-2488 A Knights Journey-深度优先搜索 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37974 A ...

  9. jzoj 1594: 【USACO】The Chivalrous Cow(骑士牛)( 待加入)

    1594: [USACO] 题目描述 Farmer John traded one of his cows for a cow that Farmer Don called 'The Knight' ...

最新文章

  1. Codeforces Round #497 (Div. 1)
  2. NetBeans 8.0的五个新性能提示
  3. 计算机三级会保研加分吗,366所高校有保研资格,除了对成绩有要求外,还有哪些要求?...
  4. 日常笔记(持续更新)
  5. unity双面显示shader
  6. softmax与sigmoid函数的理解
  7. 机房服务器配置方案文件,机房搬迁实施方案模版
  8. python怎么换背景颜色_Python给照片换底色(蓝底换红底)
  9. NLP-文本挖掘-综述
  10. 年轻人,不要太浮躁,静下心来听听【钢琴曲】
  11. Android:一个妹zhi的学习之路_心得体会
  12. vue预览excel
  13. SkyEye天目全数字实时仿真软件功能介绍
  14. 自己动手写CPU(11)——加载存储指令说明
  15. 学习smarty手记一,如何配置smarty
  16. FilterConfig.RegisterGlobalFilters 全局过滤器的用法
  17. css样式(火狐的兼容性问题)
  18. 经典问题:数据有误,一定要重传吗?
  19. 计算机网络模拟校园,计算机网络课程计-模拟校园网组网实验.doc
  20. 建立工资计算系统(1)——员工和工资

热门文章

  1. 编程培训怎么样 哪家编程培训机构靠谱
  2. 六个方法帮你写走心的文案
  3. 如何修改图片大小200kb?怎样让图片不超过200k?
  4. 性能测试中怎么检测CPU情况
  5. ibatis中resultMap和resultClass的区别 以及parameterClass 的取值
  6. ubuntu清理硬盘空间
  7. 区块链智能资产的“硬链接”思考
  8. 安卓搭建http服务器——NanoHttpd
  9. 前端开发[html+css]的实用网站分享(一)
  10. Python中的面向对象编程练习