D e s c r i p t i o n Description Description
汉诺塔问题,条件如下:
1、这里有 A、B、C 和 D 四座塔。
2、这里有 个圆盘, 的数量是恒定的。
3、每个圆盘的尺寸都不相同。
4、所有的圆盘在开始时都堆叠在塔 A 上,且圆盘尺寸从塔顶到塔底逐渐增大。
5、我们需要将所有的圆盘都从塔 A 转移到塔 D 上。
6、每次可以移动一个圆盘,当塔为空塔或者塔顶圆盘尺寸大于被移动圆盘时,可将圆盘移至这座塔上。 请你求出将所有圆盘从塔 A 移动到塔 D,所需的最小移动次数是多少。
I n p u t Input Input
莫得输入。
O u t p u t Output Output
对于每一个整数 n ( 1 ⩽ n ⩽ 12 ) n(1\leqslant n \leqslant 12) n(1⩽n⩽12),输出一个满足条件的最小移动次数,每个结果占一行。
T r a i n Train Train o f of of T h o u g h t Thought Thought
先考虑正常汉诺塔问题(就是只有三座塔)
设 A k A_k Ak为有 k k k个圆盘的最佳答案
先把 k − 1 k-1 k−1个圆盘从A柱移到B柱: A k − 1 A_{k-1} Ak−1
然后把第 k k k个圆盘移到C柱:1
再把 k − 1 k-1 k−1个圆盘从B柱移到A柱: A k − 1 A_{k-1} Ak−1
那么 A k = 2 ∗ A k − 1 + 1 A_k=2 * A_{k-1} + 1 Ak=2∗Ak−1+1
然后在考虑有四座塔
设 F k F_k Fk
则先将 j j j个圆盘从A柱移到B柱: F j F_j Fj
然后将 k − j k-j k−j个圆盘从A柱移到D柱: A k − j A_{k-j} Ak−j
(也就是普通汉诺塔问题,因为B柱不能放)
再将 j j j个圆盘从B柱移到D柱: F j F_j Fj
那么 F i = m i n j = 0 i ( 2 ∗ F j + A i − j ) F_i=min_{j=0}^{i}(2 * F_j + A_{i-j}) Fi=minj=0i(2∗Fj+Ai−j)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
ll A[15], F[15];
int main()
{
memset(F, 0x3f, sizeof(F));
A[1] = F[1] = 1;
for(ll i = 2; i <= 12; ++i)
A[i] = 2 * A[i - 1] + 1;
for(ll i = 1; i <= 12; ++i)
{
for(ll j = 0; j <= i; ++j)
F[i] = min(F[i], 2 * F[j] + A[i - j]);
printf("%lld\n", F[i]);
}
return 0;
}