Knight On the Chessboard
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相关推荐
- Knight Probability in Chessboard
Knight Probability in Chessboard 题目描述:在NxN的棋盘上,骑士走"日"字,经过K次行走之后,骑士还留在棋盘上的概率是多少? 骑士在棋盘上行走时, ...
- LWC 52:688. Knight Probability in Chessboard
LWC 52:688. Knight Probability in Chessboard 传送门:688. Knight Probability in Chessboard Problem: On a ...
- Leetcode 688.Knight Probability in Chessboard
Leetcode 688.Knight Probability in Chessboard 题目: On an NxN chessboard, a knight starts at the r-th ...
- leetcode 688. Knight Probability in Chessboard | 688. “马”在棋盘上的概率(dp,记忆化搜索)
题目 https://leetcode.com/problems/knight-probability-in-chessboard/ 题解 左神讲过类似问题: 给定5个参数,N,M,row,col,k ...
- A Knight‘s Journey(POJ-2488)
A Knight's Journey 题目 题目大意 题目思路 代码 题目 Description Background The knight is getting bored of seeing t ...
- 【LeetCode】935. Knight Dialer 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划TLE 空间换时间,利用对称性 优化空间复杂 ...
- DFS(二):骑士游历问题
在国际象棋的棋盘(8行×8列)上放置一个马,按照"马走日字"的规则,马要遍历棋盘,即到达棋盘上的每一格,并且每格只到达一次.例如,下图给出了骑士从坐标(1,5)出发,游历棋盘的一种 ...
- POJ-2488 A Knights Journey-深度优先搜索DFS
POJ-2488 A Knights Journey-深度优先搜索 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37974 A ...
- jzoj 1594: 【USACO】The Chivalrous Cow(骑士牛)( 待加入)
1594: [USACO] 题目描述 Farmer John traded one of his cows for a cow that Farmer Don called 'The Knight' ...
最新文章
- Codeforces Round #497 (Div. 1)
- NetBeans 8.0的五个新性能提示
- 计算机三级会保研加分吗,366所高校有保研资格,除了对成绩有要求外,还有哪些要求?...
- 日常笔记(持续更新)
- unity双面显示shader
- softmax与sigmoid函数的理解
- 机房服务器配置方案文件,机房搬迁实施方案模版
- python怎么换背景颜色_Python给照片换底色(蓝底换红底)
- NLP-文本挖掘-综述
- 年轻人,不要太浮躁,静下心来听听【钢琴曲】
- Android:一个妹zhi的学习之路_心得体会
- vue预览excel
- SkyEye天目全数字实时仿真软件功能介绍
- 自己动手写CPU(11)——加载存储指令说明
- 学习smarty手记一,如何配置smarty
- FilterConfig.RegisterGlobalFilters 全局过滤器的用法
- css样式(火狐的兼容性问题)
- 经典问题:数据有误,一定要重传吗?
- 计算机网络模拟校园,计算机网络课程计-模拟校园网组网实验.doc
- 建立工资计算系统(1)——员工和工资