算法概念
- 动态规划(Dynamic Programming)是一种分阶段求解的算法思想,通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(分治)的方式去解决。
- 动态规划中有三个重点概念:
最优子结构:按照最佳的方式进行拆分,用来描述问题状态与状态之间的关系;
边界:问题的边界区域,可以是除了最优子结构的其它区域;
状态转移公式(递推公式)dp方程:根据最优子结构和边界终结出来的方程。 - 优缺点:
优点:时间复杂度和空间复杂度都相当较低
缺点:难,有些场景不适用
算法例子
斐波那契数列
规律:从第3个数开始,每个数等于前面两个数的和。
分析得知:
if(i<2) 则 dp[0] = 0,dp[1] = 1;
if(i>=2) 则 dp[i] = dp[i-1] + dp[i-2];
所以:
最优子结构:fib[9] = fib[8] + fib[7]
边界:a[0] = 0; a[1] = 1
dp方程:fib[n] = fib[n-1] + fib[n-2]
实现代码如下:
package com.xxliao.algorithms.dynamic_programming;/*** @author xxliao* @description: 利用动态规划实现* 斐波那契数列:0、1、1、2、3、5、8、13、21、34、55.....* 规律:从第3个数开始,每个数等于前面两个数的和** @date 2024/6/1 1:17*/
public class Demo01 {public static void main(String[] args) {System.out.println(fib(9));}/*** @description 动态规划实现 斐波那契数列* @author xxliao* @date 2024/6/1 1:23*/public static int fib(int n) {// 定义当前数组,也就是0 ~ n 数组int[] array = new int[n+1];// 定义边界array[0] = 0;array[1] = 1;// if(i>=2) 则 dp[i] = dp[i-1] + dp[i-2]; dp方程int i = 2;for(; i <= n; i++){array[i] = array[i-1] + array[i-2];}return array[i-1]; // 循环结束加了1}
}
演示结果: