奇怪汉诺塔
题目描述
汉诺塔问题,条件如下:
这里有 A、B、C 和 D 四座塔。
这里有 个圆盘, 的数量是恒定的。
每个圆盘的尺寸都不相同。
所有的圆盘在开始时都堆叠在塔 A 上,且圆盘尺寸从塔顶到塔底逐渐增大。
我们需要将所有的圆盘都从塔 A 转移到塔 D 上。
每次可以移动一个圆盘,当塔为空塔或者塔顶圆盘尺寸大于被移动圆盘时,可将圆盘移至这座塔上。 请你求出将所有圆盘从塔 A 移动到塔 D,所需的最小移动次数是多少。
输入格式
没有输入。
输出格式
对于每一个整数1≤n≤12 ,输出一个满足条件的最小移动次数,每个结果占一行
解题思路
首先考虑3座塔的汉诺塔问题,我们设a(n)表示n个盘子3座塔的最优步数,我们需要先把n-1个盘子移到B柱上,最优步数为d(n-1),然后把A柱上的剩余一个盘子移到C柱上,步数为1,最后再把B柱上的n-1个盘子移到C柱上,最优步数也为a(n-1)。故有递推式:
a ( n ) = 2 ∗ a ( n − 1 ) + 1 a(n)=2*a(n-1)+1 a(n)=2∗a(n−1)+1
回到本题,我们设f(n)表示n个盘子4座塔的最优步数,考虑从A柱移动j个盘到B柱上,最优步数为f(j),再将n-j个盘子移到D柱上,考虑到B柱上已经有盘子了,故在3塔模式下最优步数为a(n-j),最后再将j个盘子移动到B住上,最优步数也为f(j)。考虑所有的j
for(int i=2;i<=12;i++)
a[i]=a[i-1]*2+1;
for(int i=2;i<=12;i++)
{
f[i]=2147483647;
for(int j=1;j<=i;j++)
f[i]=min(f[i],f[j]*2+a[i-j]);
}
AC代码
#include<cstdio>
#include<algorithm>
using namespace std;
int a[15],f[15];
int main()
{
a[1]=1;
for(int i=2;i<=12;i++)//初值
a[i]=a[i-1]*2+1;
f[1]=1;
printf("1\n");
for(int i=2;i<=12;i++)//递推
{
f[i]=2147483647;
for(int j=1;j<=i;j++)
f[i]=min(f[i],f[j]*2+a[i-j]);
printf("%d\n",f[i]);
}
return 0;
}