动态规划一:斐波那契数列

动态规划一:斐波那契数列

【题目】写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。斐波那契数列的定义如下: 

斐波那契数列

方法一:递归方法

public  long fib(int n){
        if(n == 0) return 0;
        if(n == 1) return 1;
        return fib(n-1)+fib(n-2);
}

以fib(5)为例:
在这里插入图片描述

深色部分的fib(3),以及fib(2)会被重复计算,当n增大时,递归树高度增加,会有更多的重复计算;因此这种递归方法的效率非常低;考虑到递归方法,会有重复计算的缺点,因此考虑设定一个数组,保存之前计算的结果,访问fib(n)时,先查看数组中对应位置的值是否存在,若存在则直接返回,若不存在,则计算后,保存到对应位置,然后返回;详见方法二:

方法二:记忆化搜索

//将数组 temp 定义为类变量,temp[i]表示fib(i)的值
long [] temp = new long[n+1];
public  long fib(int n,long[] temp){
        if(n == 0) return 0;
        if(n == 1) return 1;
        if(temp[n] == 0)
            //记忆化搜索,自上向下
            temp[n] = fib(n-1,temp)+fib(n-2,temp);
        return temp[n];

}

方法二用数组temp保存了每一步的计算结果,实现了自上向下的记忆化搜索,避免了大量的重复计算;

方法三:动态规划

 //将数组 temp 定义为类变量,temp[i]表示fib(i)的值
 long [] temp = new long[n+1];
 public long fib(int n,long[] temp){
        temp[0] = 0;
        temp[1] = 1;
        //动态规划,自底向上
        for(int i = 2;i <= n;i++)
            temp[i]=temp[i-1]+temp[i-2];
        return temp[n];
}

方法四:动态规划改进

public long fib(int n){
	        long temp0 = 0;
	        long temp1 = 1;
	        long temp2 = temp0+temp1;
	        for(int i = 2;i <= n;i++){
	            temp2 = temp1+temp0;
	            temp0 = temp1;
	            temp1 = temp2;
	        }
	        return temp2;
}

动态规划简介:

在这里插入图片描述

图中的重叠子问题,是指在减小问题规模过程中,会有多次重复的操作;例如前文方法一递归方法中提到的多次重复计算;最优子结构是指在求解最优化问题时在问题规模减小过程中,原来规模的最优化问题可以转化为子问题的最优化问题。详见《动态规划二:整数划分求积》。针对重叠子问题和最优子结构问题,有两种解决方法:记忆化搜索(自顶向下);动态规划(自底向上)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值