题目描述
汉诺塔问题,条件如下:
1、这里有 A、B、C 和 D 四座塔。
2、这里有 n n n 个圆盘, n n n 的数量是恒定的。
3、每个圆盘的尺寸都不相同。
4、所有的圆盘在开始时都堆叠在塔 A 上,且圆盘尺寸从塔顶到塔底逐渐增大。
5、我们需要将所有的圆盘都从塔 A 转移到塔 D 上。
6、每次可以移动一个圆盘,当塔为空塔或者塔顶圆盘尺寸大于被移动圆盘时,可将圆盘移至这座塔上。
请你求出将所有圆盘从塔 A 移动到塔 D,所需的最小移动次数是多少。
输入格式
无
输出格式
对于每一个整数 n n n,输出一个满足条件的最小移动次数,每个结果占一行。
数据范围
1 ≤ n ≤ 12 1≤n≤12 1≤n≤12
题解
这道题是三塔汉诺塔的进阶版
先回忆一下三塔汉诺塔:
用
d
[
i
]
d[i]
d[i]来表示解决
i
i
i盘
3
3
3塔所需要的最少步数
则有递推式
d
[
i
]
=
2
∗
d
[
i
−
1
]
+
1
d[i]=2*d[i-1]+1
d[i]=2∗d[i−1]+1(将
i
−
1
i-1
i−1个盘从
3
3
3塔移至
2
2
2塔,将第
i
i
i个盘移至
3
3
3塔,将
i
−
1
i-1
i−1个盘移回
3
3
3塔)
那么对于四塔汉诺塔的解法:
用
f
[
i
]
f[i]
f[i]来表示解决
i
i
i盘
4
4
4塔所需要的最少步数
则有递推式
f
[
i
]
=
m
i
n
(
2
∗
f
[
j
]
+
d
[
i
−
j
]
,
f
[
i
]
)
f[i]=min(2*f[j]+d[i-j],f[i])
f[i]=min(2∗f[j]+d[i−j],f[i])(将
j
j
j个盘从
1
1
1塔移至
2
2
2塔(此时为四塔模式),将第
i
−
j
i-j
i−j个盘移至
4
4
4塔(此时为三塔模式,
2
2
2塔不能使用),将
i
i
i个盘移至
4
4
4塔(此时为四塔模式,四塔上的
i
−
j
i-j
i−j个盘已固定))
code
#include<bits/stdc++.h>
using namespace std;
long long d[15],f[15];
int main()
{
memset(f,0x3f,sizeof(f));
d[1]=f[1]=1;
for(int j=2;j<=12;j++) d[j]=1+2*d[j-1];
for(int j=2;j<=12;j++)
for(int k=0;k<j;k++)
f[j]=min(f[j],2*f[k]+d[j-k]);
for(int i=1;i<=12;i++)
printf("%d\n",f[i]);
return 0;
}