个人技术分享

算法概念

  • 动态规划(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
    }
}

演示结果:
在这里插入图片描述