• 递归的Fibonacci在数羊


    一、由数羊引起的

    有一道经典的面试题是这样的。

    题目:一头母羊的寿命是5年,它会在第2年底和第4年底各生下一头母羊,第5年底死去,
    问一开始农场有1头母羊,N年后,农场会有多少只母羊?

    (假设没有公羊也会生羊,而且只只生母羊,不要较真 - -!)

    乍一看不知所云,其实慢慢分析so easy!


    思路:
    年数      羊的个数      备注
    1            1             1只羊
    2            2=1+1      生1只
    3            2             不生
    4            4=2+2      第1只在第4年生,第2只在第2年生
    5            3=4-1       第1只样死去
    6            6=3+3      第2只在4年生,第3只在第2年生,第4只在第2年生
    7            5=6-1       第2只样死去
    8            10=5+5     第3只在第4年生,第4只在第4年生,
    9            8=10-2     第3只和第4只死去
    10          16=8+8     继续生...
    规律:奇数年是1 2 3 5 8 的斐波那契数列
          偶数年是2 4 6 10 16的斐波那契数列

    所以我们首先得了解Fibonacci数列。

    二、Fibonacci数列

    【题目】一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现。

    /// <summary>
    /// 一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现
    /// </summary>
    /// <param name="pos">第几位</param>
    /// <returns>返回该位置处的数字</returns>
    public int Fib(int pos)
    {
        if (pos <= 0)
        {
            return 0;
        }
        if (pos == 1)
        {
            return 1;
        }
        int result = Fib(pos - 1) + Fib(pos - 2);
        return result;
    }
    

      


    我们还可以将递归改为非递归。利用数组就可实现。比方说:

    /// <summary> 
    /// 非递归算法计算斐波那契数,速度要比递归快 
    /// </summary> 
    /// <param name="pos">第几位</param> 
    /// <returns>返回该位置处的数字</returns> 
    public int GetNumAtPos(int pos) 
    { 
        int result = 0; 
        int[] arr = new int[1000 * 1000];
    
        arr[0] = 1; 
        arr[1] = 1;
    
        for (int i = 2; i < pos; i++) 
        { 
            arr[i] = arr[i - 2] + arr[i - 1]; 
        }
    
        result = arr[pos - 1];
    
        return result; 
    } 
    

      

    三、农场养羊问题

    了解了Fibonacci数列之后,我们继续回到数羊的问题上。根据分析的思路可以写出如下一种实现方式:

    public class Fibonacci 
    { 
        /// <summary> 
        /// 题目:一头母羊的寿命是5年,它会在第2年底和第4年底各生下一头母羊,第5年底死去, 
        /// 问一开始农场有1头母羊,N年后,农场会有多少只母羊?(假设只生母羊,不要较真 - -!) 
        /// </summary> 
        /// <remarks> 
        /// 思路: 
        ///年数      羊的个数      备注 
        ///1            1            1只羊 
        ///2            2=1+1        生1只 
        ///3            2            不生 
        ///4            4=2+2        第1只在第4年生,第2只在第2年生 
        ///5            3=4-1        第1只样死去 
        ///6            6=3+3        第2只在4年生,第3只在第2年生,第4只在第2年生 
        ///7            5=6-1        第2只样死去 
        ///8            10=5+5        第3只在第4年生,第4只在第4年生, 
        ///9            8=10-2        第3只和第4只死去 
        ///10            16=8+8        继续生... 
        ///规律:奇数年是1 2 3 5 8 的斐波那契数列 
        ///      偶数年是2 4 6 10 16的斐波那契数列 
        /// </remarks> 
        /// <param name="year"></param> 
        /// <returns></returns> 
        public int CountSheep(int year) 
        { 
            int result = 0; 
            // 奇数年 
            if (year%2==1) 
            { 
                year = (year + 1) / 2; // 折半 
                result = EvenSum(year); 
                return result; 
            } 
            // 偶数年 
            if (year%2==0) 
            { 
                year = year / 2; // 折半 
                result = OddSum(year); 
                return result; 
            } 
            return result; 
        }
    
        /// <summary> 
        /// 奇数年的Fibonacci数 
        /// </summary> 
        /// <param name="year">第几年</param> 
        /// <returns>羊的个数</returns> 
        private int EvenSum(int year) 
        { 
            int num = 0; 
            if (year <= 0) 
            { 
                return 0; 
            } 
            if (year==1) 
            { 
                return 1; 
            } 
            if (year==2) 
            { 
                return 2; 
            }
    
            num = EvenSum(year - 1) + EvenSum(year - 2);
    
            return num; 
        }
    
        /// <summary> 
        /// 偶数年的Fibonacci数 
        /// </summary> 
        /// <param name="year">第几年</param> 
        /// <returns>羊的个数</returns> 
        private int OddSum(int year) 
        { 
            int num = 0; 
            if (year<=0) 
            { 
                return 0; 
            } 
            if (year==1) 
            { 
                return 2; 
            } 
            if (year==2) 
            { 
                return 4; 
            } 
            num = OddSum(year - 1) + OddSum(year - 2); 
            return num; 
        } 
    }
    

      

    测试方法如下:

    static void Main(string[] args) 
    { 
    	int result = 0;
    
    	// 斐波那契方法测试 
    	Fibonacci fib = new Fibonacci(); 
    	//result = fib.Fib(30);
    
    	// 非递归数组方法测试 
    	//result = fib.GetNumAtPos(50);
    
    	// 数羊测试 
    	for (int i = 1; i <= 12; i++) 
    	{ 
    		result = fib.CountSheep(i); 
    		Console.WriteLine("第 " + i + " 年羊的个数为:" + result); 
    	}
    
    	
    	Console.ReadLine(); 
    }
    

      

    运行效果如下:

  • 相关阅读:
    Python数据分析入门
    非常干货之Python资源大全
    机器学习实战笔记之非均衡分类问题
    2^x mod n = 1 【杭电-HDOJ-1395】 附题
    android学习--视图列表(ListView和ListActivity)
    C++第13周(春)项目1
    多个线程怎样操作同一个epoll fd
    UVA
    自己定义progressdialog,改善用户体验
    总结个人项目设计保障5大原则
  • 原文地址:https://www.cnblogs.com/fanyong/p/FibonacciCountSheep.html
Copyright © 2020-2023  润新知