zoukankan      html  css  js  c++  java
  • 四柱汉诺塔

    思路是借鉴网上一大牛的,写的很完美了,所以一句没改,代码是自己敲的,C语言版
    变体汉诺塔
        问题描述:在经典汉诺塔的基础上加一个条件,即,如果再加一根柱子(即现在有四根柱子a,b,c,d),计算将n个盘从第一根柱子(a)全部移到最后一根柱子(d)上所需的最少步数,当然,也不能够出现大的盘子放在小的盘子上面。注:1<=n<=64;
    分析:设F[n]为所求的最小步数,显然,当n=1时,F[n]=1;当n=2时,F[n]=3;如同经典汉诺塔一样,我们将移完盘子的任务分为三步:
    (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];
    第(3)步结束后任务完成。
    故完成任务所需要的总的步数F[n]=F[x]+2^(n-x)-1+F[x]=2*F[x]+2^(n-x)-1;但这还没有达到要求,题目中要求的是求最少的步数,易知上式,随着x的不同取值,对于同一个n,也会得出不同的F[n]。即实际该问题的答案应该min{2*F[x]+2^(n-x)-1},其中1<=x<=n;在用高级语言实现该算法的过程中,我们可以用循环的方式,遍历x的各个取值,并用一个标记变量min记录x的各个取值中F[n]的最小值。
    代码如下
    代码
    #include <stdio.h>
    #define Inf 10000000
    long f[66]={0,1,3};
    long min(long a,long b)
    {
        
    return a<b?a:b;
    }
    long find(long n)
    {
        
    if (!f[n]) 
        {
            
    long i;
            f[n]
    =Inf;
            
    for (i=1;i<n;i++if (n-i<=10)//实际上答案并不大,当i值过小时有可能溢出,所以进行限制
            {
                f[n]
    =min(f[n],2*find(i)+(1<<(n-i))-1);
            }
        }
        
    return f[n];    
    }
    main()
    {
        
    long n,i;
        
    while(scanf("%d",&n)!=EOF)
        {
            printf(
    "%d\n",find(n));        
        }    
        
    return 0;
    }
  • 相关阅读:
    42. Trapping Rain Water
    223. Rectangle Area
    645. Set Mismatch
    541. Reverse String II
    675. Cut Off Trees for Golf Event
    安装 VsCode 插件安装以及配置
    向上取整 向下取整 四舍五入 产生100以内随机数
    JS 判断是否为数字 数字型特殊值
    移动端初始配置,兼容不同浏览器的渲染内核
    Flex移动布局中单行和双行布局的区别以及使用
  • 原文地址:https://www.cnblogs.com/waterfalleagle/p/1949433.html
Copyright © 2011-2022 走看看