动态规划算法
数学归纳法引出动态规划算法的思想
我们解决动态规划问题一般分为四步:
1、确定状态
2、转移方程
3、初始条件和边界情况
4、计算顺序
经典例题:
1、斐波拉契数列(自顶向下)递归版本
这个代码的时间复杂度是2^n,也就是指数递增,我们经过测试当求一个很大数字的时候,这个时间可想而知很长
1 public static int Fibonacci(int n) { 2 if(n<=0) 3 return 0; 4 if(n == 1 || n == 2) 5 return 1; 6 return Fibonacci(n-1)+Fibonacci(n-2); 7 } 8 }
动态规划版
1 public static int topDownFibonacci(int n, int[] arr) { 2 // 初始化arr数组的所有值为-1,表示该斐波那契数列还没有被计算 3 for (int i = 0; i < arr.length; i++) { 4 arr[i] = -1; 5 } 6 7 // 求第n个数是多少 8 return fibonacci(n, arr); 9 } 10 11 public static int fibonacci(int n, int[] arr) { 12 if (arr[n] != -1) { 13 return arr[n]; 14 } 15 16 int result = fibonacci(n - 1, arr) + fibonacci(n - 2, arr); 17 // 标记第n个数已经计算好了,下次可以直接拿 18 arr[n] = result; 19 // 返回给调用者,因为这是上一级调用者要求的数,现在求好了可以往上返回。 20 return arr[n]; 21 }
迭代版
1 /** 2 * 迭代版 3 * @param n 4 * @return 5 */ 6 public static int fibonacci(int n) { 7 if (n <= 0) { 8 return 0; 9 } 10 if (n == 1) { 11 return 1; 12 } 13 int f1 = 0; 14 int f2 = 1; 15 int result = 0; 16 for (int i = 2; i <= n; i++) { 17 // 递推公式 18 result = f1 + f2; 19 // 将原来的f2赋值给f1 20 f1 = f2; 21 // 将结果赋值给f2 22 f2 = result; 23 } 24 25 return result; 26 }