动态规划求解裴波那契数列

来源:互联网 发布:在淘宝开童装店 编辑:程序博客网 时间:2024/05/21 22:33

       裴波那契数列,又称兔子数列。是指1,1,2,3,5,……这样的数列。从第三项开始,每一项是其前两项之和。通过数学表达式来表达,即f(n)=f(n-1)+f(n-2)(n>2)。本文研究的问题是关于给出裴波那契数列的第n项求解。

       在数学上,可以通过特征方程的方法求解出裴波那契数列的通项公式,如下图所示:

      

       

      对于程序员来说,要将这样的方程式求解方式转换为程序有些复杂。因此,程序中会使用递归的方式对裴波那契数列进行求解。

    //f(n) = f(n-1)+f(n-2)    public  static int getByReCurSion(int n){        if(n==1||n==2){            return 1;        }else{            return getByReCurSion(n-1)+getByReCurSion(n-2);        }    }

       这种方法在n较小时效果还不错。但是随着n的增大,时间消耗越来越大。这是因为,计算f(n)时,会计算f(n-1)一次,f(n-2)一次,计算f(n-1)时,又会计算f(n-2)一次,对于f(3),f(4)这样的项重复计算了很多次。这里考虑用动态规划的备忘录法进行优化,即用一个数组来缓存每个项。

       最后完整的代码如下:

       

/** * @author shenwc on 2017/12/8 */public class question1 {    private static int[] f = new int[100];    //f(n) = f(n-1)+f(n-2)    public  static int getByReCurSion(int n){        if(n==1||n==2){            return 1;        }else{            return getByReCurSion(n-1)+getByReCurSion(n-2);        }    }    //基于动态规划的备忘录法求解裴波那契数列    public static int getDynamic(int n){        if(n==1||n==2){            f[n] = 1;        }else{            if(f[n]==0){                f[n]=getDynamic(n-1)+getDynamic(n-2);            }        }        return f[n];    }    public static void main(String[] args) {        long time1 = System.currentTimeMillis();        System.out.println(getDynamic(40));        long time2 = System.currentTimeMillis();        System.out.println("动态规划耗时"+(time2-time1)+"毫秒");        long time3 = System.currentTimeMillis();        System.out.println(getByReCurSion(40));        long time4 = System.currentTimeMillis();        System.out.println("递归耗时"+(time4-time3)+"毫秒");    }}
运行结果如下:

        

102334155动态规划耗时1毫秒102334155递归耗时464毫秒

可以看到优化了大概了100倍速度。

       

     

原创粉丝点击