动态规划(DP)

简介: 动态规划(DP)

动态规划(DP)


动态规划,常用于:数学,管理科学,计算机科学,经济和生物信息学。


特征:一个问题,可以拆分成一个一个的子问题,解决子问题,顺带解决这个问题


核心思想:拆分子问题,记住过程,减少重复运算。


例子


1+1+1+1+1+1=? 等于6


在上面式子的再加上一个“ 1+”。答案是多少?


直接通过以往计算过的答案,再加1


例题:青蛙跳阶问题:


一只青蛙,可以一次跳上1级台阶,也可以一次跳上2级台阶。求这只青蛙跳10级台阶有多少种跳法?

分析:

要跳到第10级台阶,要么从第8级台阶,跳2级到第10级。要么从第9级跳1步到第十级。

要跳到第9级:可以从第8级跳1步到达,也可以从第7级跳两步到达。

要跳到第8级:可以从第7级跳1步到达,也可以从第6级跳两步到达。

............


方法一:暴力递归


//暴力递归
//时间复杂度=解决子问题的时间*子问题个数(存在大量重读运算)
public class 青蛙跳阶 {
    public static void main(String[] args) {
        long l1 = System.currentTimeMillis();
        int ways = ways(30);
        long l2 = System.currentTimeMillis();
        System.out.println("有" + ways + "种跳法");
        System.out.println(l2 - l1);
    }
    public static int ways(int n) {
        if (n == 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        return ways(n - 1) + ways(n - 2);
    }
}


该方法时间复杂度过大,程序运行速度较慢,考虑使用数据字典进行优化


方法二:使用数据字典存储子问题的解(暴力递归的优化)


public class 青蛙跳阶_数据字典优化 {
    public static void main(String[] args) {
        long l1 = System.currentTimeMillis();
        int ways = ways(30);
        long l2 = System.currentTimeMillis();
        System.out.println("有" + ways + "种跳法");
        System.out.println(l2 - l1);
    }
    static Map<Integer, Integer> map = new HashMap();
    public static int ways(int n) {
        if (n == 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        if (map.containsKey(n)) {
            return map.get(n);
        } else {
            map.put(n, ways(n - 1) + ways(n - 2));
            return map.get(n);
        }
    }
}


方法三:动态规划


动态规划和带字典的递归有些不同,但解法类似。都有减少重复运算。


动态规划的特征:


最优子结构:f(n) = f(n-1) + f(n-2), f(n-1)和 f(n-2)就是f(n)的最优子结构。


状态转移方程:f(n) = f(n-1) + f(n-2)


边界:f(1) =1 ,f(2) = 2


重叠子:重复的运算:f(10) = f(9) + f(8),f(9) = f(8)+f(7). f(8)就是重叠子


public class 青蛙跳阶_动态规划 {
    public static void main(String[] args) {
        System.out.println(ways(10));
    }
    public static int ways(int n) {
        if (n == 1) {
            return 1;
        }
        if (n == 2) {
            return 2;
        }
        int a = 1;
        int b = 2;
        int temp = 0;
        for (int i = 3; i <= n; i++) {
            temp = a + b;
            a = b;
            b = temp;
        }
        return temp;
    }
}


动态规划的解题思路


什么样的问题适用动态规划?


如果一个问题,可以把所有的答案穷举出来,而且存在重叠子问题,就可以考虑使用动态规划。


动态规划的经典应用场景:


最长递增子序列 ---20年蓝肽子问题


最小距离 --- 数字三角形


背包问题


凑零钱问题


等等等。。。


动态规划的解题思路


核心思想:拆分子问题,记住过程,减少重叠子运算


穷举分析


确定边界


找出规律,确定最优子结构


写出状态转移方程


代码实现

目录
相关文章
|
机器学习/深度学习 自然语言处理 自动驾驶
深度学习的应用实例:重塑各个领域的未来
深度学习的应用实例:重塑各个领域的未来
608 0
|
10月前
|
域名解析 缓存 网络协议
减少域名dns解析时间
域名解析中的TTL值设置多少合适
557 5
|
5月前
|
JavaScript 前端开发 中间件
除了 Pinia,还有哪些状态管理库可以实现类似的中间件功能?
除了 Pinia,还有哪些状态管理库可以实现类似的中间件功能?
233 73
|
JavaScript 小程序 Java
基于微信小程序的宠物寄养平台的设计与实现(源码+lw+部署文档+讲解等)
基于微信小程序的宠物寄养平台的设计与实现(源码+lw+部署文档+讲解等)
265 1
|
容灾 流计算
美团 Flink 大作业部署问题之Checkpoint 的 metadata 文件包含什么信息
美团 Flink 大作业部署问题之Checkpoint 的 metadata 文件包含什么信息
179 1
|
机器学习/深度学习 安全 测试技术
API 接口测试的发展前景展望
在数字化时代,API已成为软件系统集成的核心。随着微服务架构普及与分布式系统增多,API数量激增,对接口测试需求大幅提升。智能化测试借助AI技术提高效率与质量,并降低成本。新技术如容器化和服务化架构催生新型API,推动测试方法不断创新。行业数字化转型与云服务发展进一步强调API测试重要性,开放API生态建设亦依赖严格测试确保安全与正确性。面对网络安全威胁,API安全测试愈发关键。尽管多协议并存和技术挑战带来复杂性,高端测试人才短缺,但API测试前景广阔,将持续发挥关键作用并适应新需求。
|
Ubuntu 虚拟化
Ubuntu——VMware安装后网络提示线缆已拔除
Ubuntu——VMware安装后网络提示线缆已拔除
300 0
|
机器学习/深度学习 人工智能 自然语言处理
探索机器学习在金融技术中的应用
本文将深入探讨机器学习技术在金融技术领域中的创新应用,并分析其在风险管理、算法交易和客户服务优化等方面的实际效果。文章将结合最新的行业数据和案例研究,展示机器学习如何推动金融服务的智能化转型,同时讨论实施过程中的挑战与未来发展趋势。通过本文,读者将获得对金融领域中机器学习应用的全面了解,包括其潜在价值及面临的主要问题。
205 0
|
存储 数据处理 图形学
什么是帧同步技术?
【5月更文挑战第3天】什么是帧同步技术?
646 9
|
缓存 开发工具 git
pip常用命令和一些坑
pip常用命令和一些坑
259 0