题目大意:将汉诺塔中的3跟柱子改为4根,求盘子数为1到12时将全部盘子从第一根移动到最后一根需要移动的次数
题目分析:当柱子数为3跟时,移动次数为2^n-1.当柱子数为4的时候,可以利用2根空的柱子移动盘子,盘子数n为1,2,3时
只需按顺序移动,各需1,3,5次,4个盘子以上:
(1)首先移动其中的几个盘子
(2)把剩余的盘子移动到指定的位置
(3)把(1)的盘子移动到(2)的上面
执行(1)和(3)的时候有两根空柱子可以利用,执行(2)的时候只有一根柱子利用,此时yu柱子数为3的时候情况相同
例如:当n=4的时候,如果(1)移动2个盘子,则需3次,(2)移动剩下的两个盘子,需要3次,然后把(1)的2个盘子移动到(2)上面
也需要3次,共需9次;如果(1)移动3个盘子,需要5次,(2)移动剩下的1个盘子,需要1次,然后把(1)的3个盘子移动到(2)上面
也需要5次,共需11次;如果(1)移动1个盘子,需要1次,(2)移动剩下的3个盘子,需要7次,然后把(1)的一个盘子移动到(2)上面
也需要1次,共9次。所以9才是最少的移动次数。但是,不知道如何分得到的才是最少的次数。所以要全部求出,比较求出最小的,分别求(k,n-k)(1<k<n)
View Code
#include<stdio.h> #include<math.h> int table[13]={0,1,3,5}; int hanoi(int k,int m) { int cost=0; cost+=table[k]*2; //执行(1)(3),执行(1),(3)需要的次数相同 cost+=(int)pow(2,m)-1; //执行(2)与柱子数为3的时候情况相同 return cost; } int main() { int i,j,cost; for(i=1;i<=12;i++) { if(i>3) { table[i]=999999999; for(j=1;j<i;j++) //比较求出最小值 { cost=hanoi(j,i-j); table[i]=table[i]>cost?cost:table[i]; } } printf("%d\n",table[i]); } return 0; }
不过对于此题,由于输出结果相同,求出后,可写出程序直接输出所有的结果
View Code
#include<stdio.h> int main() { puts("1\n3\n5\n9\n13\n17\n25\n33\n41\n49\n65\n81"); return 0; }