简要题意:
给定一个初始棋盘,每次一个马可以跳到空位(不考虑蹩腿问题)。求到达目标棋盘的最小步数。
本题其实是 八数码难题 的一个强化版,可以去看看 P1379 八数码难题 题解.
首先本题肯定是 搜索。
-
状态:棋盘压缩成字符串。
-
答案:记录步数。
-
如何实现:深度优先搜索,即 dfs \texttt{dfs} dfs.
咦? dfs \texttt{dfs} dfs 的效率不是严格不优于 bfs \texttt{bfs} bfs 的么?为什么还要用它呢?
嗯,只要我们加上一点点优化, dfs \texttt{dfs} dfs 就不叫 dfs \texttt{dfs} dfs 了,它换了一个名字,叫做 A* \text{A*} A* 算法;如果你再优化 亿点点,就可以再升级为 IDA* \text{IDA*} IDA* 算法!
那么,这些优化是什么?为什么只有 dfs \texttt{dfs} dfs 才能用呢?而 A* , IDA* \text{A* , IDA*} A* , IDA* 都是什么呢?
我们来一层层解决这个问题。
首先,我们画出一个搜索状态图(大概)。
红色是起点状态,绿色是目标状态。在两红色轮廓线中的是我们要搜索的所有状态。
可是,你会发现有一些东西完全不用搜索。就比方说,如果跳了一步之后,反而比原来不跳更差了,那么这步就不用做了。
对,这就是一个有力的剪枝,这样的搜索方式被称为 A* \text{A*} A*.
那么,如果确定 当前状态的优劣性呢?
这时我们引进了 估价函数 h h h 的概念。
h h h 它的主要作用是估计当前状态到目标状态的步数。(与实际答案相差很大,但可作为参考)其特点在于, h h h 返回的是最小可能的步数,不可能从当前状态用 < h <h <h 步完成问题。
所以,如果当前状态为 x x x,从起点走了 g x g_x gx 步到达 x x x,然后其估价函数 咕值函数 为 h x h_x hx, f x f_x