题目大意:将汉诺塔中的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;
}
posted on 2012-04-30 21:45  pcoda  阅读(826)  评论(0编辑  收藏  举报