斐波那契和记忆优化+动态规划
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)
就是从第三个数开始等于前两个数的和
斐波那契递归
import java.util.Scanner;
public class 斐波那契 {
static int count=0;//fib调用次数
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int a = input.nextInt();
System.out.println(fib(a));
System.out.println(count);//递归次数是2的n次方
}
static int fib(int n) {
count++;
if (n == 1 || n == 2) {
return 1;
}
return fib(n-1)+fib(n-2);
}
}
n取到20时 调用次数达到13529
记忆优化后
运算后存到数组中,不进行重复调用
当n取到20时,调用次数为37.
import java.util.Scanner;
public class 斐波那契算法记忆优化 {
static int count = 0;//fib调用次数
static int[] memory = new int[100];
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int a = input.nextInt();
System.out.println(fib(a));
System.out.println(count);//递归次数大幅度减少
}
static int fib(int n) {
count++;
if (n == 1 || n == 2) {
memory[n] = 1;//将n=1,n=2时存入记忆数组中代表1,2已经算过memory[1]=1;memory[2]=1;
return memory[n];
}
if (memory[n] == 0) {//如果没访问过
memory[n] = fib(n - 1) + fib(n - 2);
} else {
return memory[n];//记忆化搜索,已经算过了,不需要再算
}
return memory[n];
}
}
动态规划
假如没有学过动态规划也是可以直接看懂的
直接用数组来理解嘛不就行了
动态规划和记忆化搜索主要是减少调用次数
用数组来保存f(n),想算f(n)
反正f(1)----f(n-1)都是要算的。
对吧
说动态规划是打表法确实很形象
import java.util.Scanner;
public class 斐波那契动态规划 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int[] dp=new int[n+1];
dp[1]=1;
dp[2]=1;
for(int i=3;i<n+1;i++ ) {
dp[i]=dp[i-1]+dp[i-2];
}
System.out.println(dp[n]);
}
}