c_递归和数列:汉诺塔

/* 
现在有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘,现在把所有盘子一个一个移动到柱子C上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方,请输出实现最小移动次数的方案。
盘子不超过20

输入
多组数据,每组一个整数n
输入0 结束

输出
输出最少步骤数

样例输入
1
2
3
0
样例输出
1
3
7 */
/* 做这道题:
1.模型抽象:将盘子的大小抽象为数字的大小,这样表示和画草图比较方便和直观.
2.考虑了贪心的策略:直接抽出放置需要的最理想步骤(最后没用上,但和递归还是有所联系)
3.考虑了递推(递归):解决更大规模的f(n)时尝试和f(n-1)或者时更小规模的已解决的f(x)建立方程(递推关系);为了之后的推理清晰,再重申一下f(x)含义:
f(x)是指:在含有x(或则更多的盘子的柱子上),将x个盘子都搬到另一个柱子(这个柱子为空(视为无穷大)或者它已有的盘子级别>x),所需要的步骤数
    事实上,递推的方法中含有基本的的迭代(参数迭代) 
4.情景逆推:(假设前头的准备工作已经执行就绪),放入C柱子的第一个盘必须时最大的,我们就考虑在放置这个最大盘到C柱时三柱的盘子分布形式
位 各柱子上的盘个数:{n-1,1,0}对应的排放状况(记为状态p1): ( 1~n-1,n,C(0(空))),其中A/B等地位!(三角);从这个状态开始操作到全部完成(在C柱上(1~n的排列)),需要+1+f(n-1)次操作;
  那么在状态p1中的(1~n-1)这个柱子如何得到?任然借助小规模已解决的f(x)来处理:它可以由A柱(1~n)通过f(x= n-1)次操作,来达到p1状态
5.综合p1状态之前的需要f(n-1)次,p1之后需要  1+f(n-1) 次,则f(n) = 1 + 2f(n-1);
6.优化位通向公式:借助数列知识:通过配凑,1/2(2f(n) + m) = (2f(n-1) + m);联立5中的原始方程,解得m = 2;...f(n) = 2^n-1; 
}
*/
/* 公式优化版:
 */
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

    //在此下方插入自定义函数对的声明:

//主函数main
int main()
{
        int n;
        int f;

       // while (scanf("%d", &n) != 0)//错误.
       
        //f(n);
        while (scanf("%d", &n) , n != 0)//&& n != 0
        {
            f = pow(2, n) - 1;
            printf("%d\n", f);
        }
        return 0;
        return 0;
} 
/*
#include <stdio.h>
#include <string.h>
    //在此下方插入自定义函数对的声明:
int f(int );
//主函数main
int main()
{
    int n;
    while(scanf("%d",&n) != EOF)
    //f(n);
     printf("%d\n",f(n));
    return 0;
} 
    //在下方编写自定义函数:
int f(int n)
{
    if(n == 1)
    {
        return 1;
    }
    return f(n-1) * 2 + 1;
} */

f(n)表示将A/B柱上的n个盘子满足规则得全部移动到C柱(或B柱)所需呀的移动次数在这里插入图片描述

posted @ 2023-02-18 11:28  xuchaoxin1375  阅读(25)  评论(0)    收藏  举报  来源