zoukankan      html  css  js  c++  java
  • 斐波那契数列Log(n)算法

    想法源于题目:一个人一次可以上一个台阶,也可以上两个台阶,问上到20级台阶有多少种走法?

    这就是一个斐波那契数列:登上第一级台阶有一种登法;登上两级台阶,有两种登法;登上三级台阶,有三种登法;登上四级台阶,有五种方法……所以,1,2,3,5,8,13……

    我们也会发现:

    f(3) = f(2) + f(1);

    f(4) = 2*(f2)+1*f(1);

    f(5) =  3*(f2) + 2*f(1);

    f(6) = 5*f(2) + 3*f(1);

    ..........

    f(n) = a*f(x) + b * f(y);

    a,b同样是斐波那契数列中的数;同时发现当:

    a+x == n &&  b+y ==n-1 && x == y+1时等式成立;

    可以得到如下O(log(n))的算法:

            /// <summary>
            
    /// 基本原理为:
            
    /// n为偶数时f(n)=f(n/2)*f(n/2)+f(n-1)*f(n-1);
            
    /// n为基数时f(n)=f(n/2+1)*f(n/2)+f(n/2)*f(n/2-1);
            
    /// </summary>
            
    /// <param name="n"></param>
            
    /// <returns></returns>
            public static long Fn2(int n)
            {
                if (1 < n)
                {
                    var steps = new Stack<int>();
                    while (n > 2
                    {
                        steps.Push(n);
                        n /= 2;
                    } 

                    long r1 = 2, r2 = 3;
                    while (steps.Count > 0
                    {
                        int tmp = steps.Pop();
                        if (3 < tmp)
                        {
                            long tr1;
                            long tr2;
                            if (0 == tmp%2)
                            {
                                tr1 = 2*r1*r1 + r2*r2 - 2*r1*r2;
                                tr2 = 2*r1*r2 - r1*r1;
                                r1 = tr1;
                                r2 = tr2;
                            }
                            else
                            {
                                tr1 = 2*r1*r2 - r1*r1;
                                tr2 = r1*r1 + r2*r2;
                                r1 = tr1;
                                r2 = tr2;
                            }
                        }
                        else
                        {
                            r1 = 3;
                            r2 = 5;
                        }

                    }
                    return r1;
                }
                if (1 == n) return 1;
                return -1;

            }
  • 相关阅读:
    Douglas-Peucker 轨迹压缩算法
    Marching squares 算法 获取轮廓(contour tracing)
    创建Mesh->格子地图转NavMesh->可破坏墙壁
    StretchedBillboard 实现
    程序员的微创业
    买云服务器有推荐吗?国内知道有腾讯云、阿里云...等等,不知道该选哪个好了,另外优惠吗?
    我的阿里云5年
    2021阿里云、腾讯云、华为云、滴滴云评测比较
    终于找到可以一文多发的平台了!
    2019年最新阿里云主机优惠购买指南
  • 原文地址:https://www.cnblogs.com/end/p/2225723.html
Copyright © 2011-2022 走看看