不妨设 $dp[i][j][k]$ 表示 $i$ 个圆盘从第 $j$ 杆移动到第 $k$ 杆的最小花费。现在要求 $n$ 个在第 $1$ 杆的圆盘移动到第 $3$ 杆上,因此最终的答案就是 $dp[n][1][3]$。
根据一般汉诺塔的移动方法,想要移动 $i$ 个圆盘,就需要先解决顶上 $i - 1$ 个圆盘的移动问题。又因为汉诺塔只有 $3$ 根柱子,所以我们也可以根据这个思路取设计转移方程。假设现在有 $n$ 个圆盘在第 $1$ 杆上,需要移动到 第 $3$ 杆上,因不同的路径的花费不同,所以我们可以先将顶上 $i - 1$ 个盘子移动到第 $2$ 根或第 $3$ 根杆上,计算哪一个花费最小,如图所示:

现在设 $dis[i][j]$ 表示将圆盘从杆 $i$ 移动到杆 $j$ 需要花费的金钱数。
根据手绘的垃圾图:
- 第一种移动方式的花费为 $n - 1$ 个盘子从 $1$ 移到 $2$ 的最小花费加上将底部的圆盘从 $1$ 移动到 $2$ 所需的花费,即 $dp[i - 1][1][2] + dis[1][2]$。
- 第一种移动方式分成三部分:
① $i - 1$ 个盘子从 $1$ 移到 $3$,底部的圆盘从 $1$ 移动到 $2$;
② $i - 1$ 个盘子从 $3$ 移到 $1$,底部的圆盘从 $2$ 移动到 $3$;
③ $i - 1$ 个盘子从 $1$ 移到 $3$。
把所有的花费合并起来就是:$dp[i - 1][1][3] + dis[1][2] + dp[i - 1][3][1] + dis[2][3] + dp[i - 1][1][3]$。
最后,我们把这两种不同的花费取最小值就是 $dp[i][j][k]$ 的答案。总结一下,转移方程就是:$dp[i][j][k] = \min (dp[i - 1][j][l] + dp[i - 1][l][k] + dis[j][k],dp[i - 1][j][k] + dis[j][l] + dp[i - 1][k][j] + dis[l][k] + dp[i - 1][j][k]) (j\neq k)$。($l$ 想必就是中间的一个媒介盘了)
有了转移方程,代码也就好写了,时间复杂度为 $O(n)$。
1 |
|