[递推]B. 【例题2】奇怪汉诺塔
B . 【 例 题 2 】 奇 怪 汉 诺 塔 B. 【例题2】奇怪汉诺塔 B.【例题2】奇怪汉诺塔
题目描述
汉诺塔问题,条件如下:
- 这里有 A A A、 B B B、 C C C 和 D D D 四座塔。 这里有 n n n个圆盘, n n n 的数量是恒定的。
- 每个圆盘的尺寸都不相同。
- 所有的圆盘在开始时都堆叠在塔 A A A上,且圆盘尺寸从塔顶到塔底逐渐增大。
- 我们需要将所有的圆盘都从塔 A A A 转移到塔 D D D 上。
- 每次可以移动一个圆盘,当塔为空塔或者塔顶圆盘尺寸大于被移动圆盘时,可将圆盘移至这座塔上。
- 请你求出将所有圆盘从塔 A A A 移动到塔 D D D,所需的最小移动次数是多少。
输入格式
没有输入。
输出格式
对于每一个整数 n ( 1 ≤ n ≤ 12 ) n(1 ≤ n ≤ 12) n(1≤n≤12),输出一个满足条件的最小移动次数,每个结果占一行。
题目解析
看题目,是汉诺塔,只是常规的三塔变成了四塔.
那么我们就考虑四塔的做法.
首先我们定义
d
i
d_{i}
di为三塔时
n
n
n个盘从
A
A
A塔到
C
C
C塔所需的步数.
那么可以得出(证明略):
d
1
=
1
d_{1} = 1
d1=1
d i = d i − 1 ∗ 2 − 1 ( i > 1 ) d_{i} = d_{i-1}*2-1~~~~~~~~~~~~~~(i>1) di=di−1∗2−1 (i>1)
然后我们定义 f ( i ) f(i) f(i)为四塔汉诺塔的最优步数为考虑四塔汉诺塔的算法思想,叫Frame算法:
-
用四柱汉诺塔算法把 A A A柱上部分的 n − r n- r n−r个碟子通过 C C C柱和 D D D柱移到 B B B柱上(为 f ( n − r ) f( n- r ) f(n−r)步)。
-
用三柱汉诺塔经典算法把 A A A柱上剩余的 r r r个碟子通过 C C C柱移到 D D D柱上(三塔汉诺塔 r r r盘的步数)。
-
用四柱汉诺塔算法把 B B B柱上的 n − r n-r n−r个碟子通过 A A A柱和 C C C柱移到 D D D柱上(为 f ( n − r ) f(n-r) f(n−r)步)。
-
依据上边规则求出所有 r ( 1 ≤ r ≤ n ) r(1≤r≤n) r(1≤r≤n)情况下步数 f ( n ) f(n) f(n),取最小值得最终解。
f [ i ] = m i n { f [ i ] 2 ∗ f [ j ] + d [ i − j ] f[i] = min \left\{\begin{matrix} & f[i]\\ & 2 * f[j] + d[i - j]\\ \end{matrix}\right. f[i]=min{f[i]2∗f[j]+d[i−j]
Code
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll d[305], f[305];
int main ()
{
d[1] = f[1] = 1;
for (int i = 2; i <= 12; ++ i)
d[i] = d[i - 1] * 2 + 1;
for (int i = 2; i <= 12; ++ i)
{
f[i] = 999999999;
for (int j = 1; j <= i; ++ j)
f[i] = min (f[i], 2 * f[j] + d[i - j]);
}
for (int i = 1; i <= 12; ++ i)
printf ("%d\n", f[i]);
return 0;
}