B4579 [GESP202609 四级] 新汉诺塔 题解
欢迎报名洛谷网校,报名课程可以获得对应组别的知识点讲解与答疑服务,期待和大家一起进步!点击图片即可报名。
:::align{center} :::
先看最大的盘子。它在最下面,所以要移动它,必须先把上面的小盘子全部搬走。它要落到的柱子也必须空着,否则就会把大盘压在小盘上。三个柱子只有一个可以放这些小盘子,这就帮我们确定了每一步该怎么做。
搬一整叠盘子时,需要记住两种情况。第一种是搬到沿箭头的下一根柱子,例如从 f 次和 g 次,接下来利用这两个答案,多算一层。
先算从 g 次。然后最大盘从 g 次。合起来,新答案是
再算题目要求的从
- 小盘子从
A 搬到C ,需要g次,让最大盘能够移动。 - 最大盘从
A 搬到B ,用1 次。 - 小盘子从
C 搬到A ,需要f次,让柱子C 空出来。 - 最大盘从
B 搬到C ,用1 次。 - 小盘子从
A 搬到C ,需要g次,叠在最大盘上。
把这些次数加起来,新答案就是
为什么这样得到的是最少次数?最大盘第一次移动前,小盘必须让路;最大盘最后一次移动后,小盘必须搬到它上面。这两头的工作都省不掉。最大盘如果多绕一圈,小盘还得在它的几次移动之间额外让路,却不能省掉开头和结尾的工作。所以多绕圈不会更省,按上面的步骤走就可以。
没有盘子时,不需要移动,所以开始时 f = 0、g = 0。根据这两个数,可以算出 f = 1、g = 2;g 就是
每轮都要先算好两个新答案,再一起换掉旧答案。代码用 nf、ng 暂时保存新结果,防止第二个计算不小心用了已经改过的 f。最后输出 g,因为题目要的是从
参考代码:
for (int i = 1; i <= n; ++i) {
// 先用小一层的答案,算出这一层的两个答案。
long long nf = ________;
long long ng = ________;
f = nf;
________;
}