什么是动态规划
动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。
从斐波那契数列数列看如何从暴力递归到动态规划
什么是菲波那切数列
菲波那切数列的规律非常简单:从第三项开始,每一项都等于前两项之和。具体来说,数列的前几项是:0、1、1、2、3、5、8、13、21、34、……
暴力递归解法
/**
* 暴力递归
* @param N
* @return
*/
public static int f(int N ){
if (N == 1 || N == 2){
return 1;
}
return f(N -1)+ f(N - 2);
}
暴力递归写法很简单,但里面有个问题.
例如:我们计算f(6) 需要计算f(5) + f(4)
计算f(5) = f(4) + f(3)
发现没 f(4) 就要跑了两次。因此我们就想到可以用缓存把状态记录下来
递归+缓存
/**
*
* @param N
* @return
*/
public static int feibo(int N){
int[] ints = new int[N + 1];
int ans = process(N,ints);
return ans;
}
/**
* 状态缓存
* @param N
* @param
* @return
*/
public static int process(int N, int[]ans){
if (N == 1 || N == 2){
return 1;
}
if (ans[N] == 0){
ans[N] = process(N -1)+ process(N - 2);
}
return ans[N];
}
动态规划解法
动态规划解法和递归加缓存的区别在于,每一次要计算的 F(N) 的值所依赖的 F(N - 1) 和 F(N - 2) 一定已经被计算出来了。
直接上代码
/**
*
* @param N
* @param
* @return
*/
public static int f(int N, int[]ans){
ans[1] = 1;
ans[2] = 1;
for (int i = 3; i <= N ;i++){
ans[i] = ans[i - 1] + ans[i - 2];
}
return ans[N];
}
/**
*
* @param N
* @return
*/
public static int feibo(int N){
int[] ints = new int[N + 1];
int ans = f(N,ints);
return ans;
}