题目大意:题目在这
本来经典的汉诺塔问题是把盘子在三根柱子上移动,现在多了一根柱子,让你求有了这根柱子的帮助最少需要移动几步可以把盘子从一根柱子上完全移动到另一根柱子上。
题目思路:
结合原来的经典汉诺塔问题,可以考虑到显然是一个递归问题,
设F[n]为所求的最小步数,我们将移完盘子的任务分为三步:
(1)将x(1<=x<=n)个盘从a柱依靠b,d柱移到c柱,这个过程需要的步数为F[x];
(2)将a柱上剩下的n-x个盘依靠b柱移到d柱(注:此时不能够依靠c柱,因为c柱上的所有盘都比a柱上的盘小)这时移动方式相当于是一个经典汉诺塔,即这个过程需要的步数为2^(n-x)-1
(3)将c柱上的x个盘依靠a,b柱移到d柱上,这个过程需要的步数为F[x];
任务完成!!!
可以看到,我们有很多种放法来移动,具体在那个x上,每次选择几个盘子呢?因为题目要求找出最小移动步数,所以我们可以遍历 0 < x < n得min { 2 * F [ x ] + 2 ^ ( n - x ) - 1};
题目代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#define INF 9999999
#define maxn 70
using namespace std;
long long f[maxn];
int main()
{
int i,n,j;
f[1]=1;
f[2]=3;
for(i=3;i<=64;i++)
{
int minn=INF;
for(j=1;j<i;j++)
{
if(2*f[j]+pow(2,i-j)-1<minn)//找出最小的移动次数
minn=2*f[j]+pow(2.0,i-j)-1;
}
f[i]=minn;
}
while(~scanf("%d",&n))
{
printf("%lld\n",f[n]);
}
return 0;
}
呼呼