• 浅谈动态规划


    浅谈动态规划


    前言

    ​ 本蒟蒻认为,在算法竞赛中,最重要的两个算法就是动态规划和搜索。后者可以暴力骗分,也可通过剪枝或记忆化、迭代加深等优化来解决问题。而前者则可以在非指数级时间复杂度内解决许多抽象而复杂的问题。


    定义

    ​ 动态规划($$DP,Dynamic Programming$$)是求解决策问题最优解的算法。

    ​ 一般来说,动态规划可被拆分成三个部分:状态决策阶段。也有三个基本条件:子问题重叠性无后效性最优子结构性质

    1.状态、决策、阶段:

    ​ 为了降低求解的时间复杂度,动态规划算法把原问题视作若干个重叠子问题的逐层递进,每个子问题都有一个状态,构成整个问题的一个阶段,并通过不同的决策方案向更深层问题转移。

    2.子问题重叠性、无后效性、最优子结构性质

    ​ 动态规划将问题分成了若干个子问题,而这些子问题的解决方案被储存在一个表中,而不是需要时再重复计算(类似于记忆化搜索)。而当一个问题,没有共同的子问题,也就是说,其所有的子问题都需要重新计算(无子问题重叠性),那么动态规划是没有用的。

    ​ 在动态规划中,一个子问题通过决策转移至后续问题,而这个子问题不能被后续问题所影响,这就是无后效性。也就是说,如果将动态规划的状态转移成一张图,那么这张图应该是一张有向无环图,而转移顺序应该是这张图的拓扑序

    ​ 对于一个问题,它可以由多个子问题到达,也就是说,下一阶段的最优解应该能够由前面各阶段子问题的最优解导出,这个条件被称作最优子结构。对于一个问题,其的最优解是由前阶段最优子状态,再与最优转移决策综合而来。


    类别与优化

    ​ 对于动态规划,本蒟蒻把其分为了这几个类别

    ​ 1.线性DP

    ​ 2.区间DP

    ​ 3.树形DP

    ​ 4.状压DP

    ​ 5.计数DP

    ​ 6.数位DP

    ​ 而DP的转移有时需要时空上的优化,如:

    ​ 1.优化状态

    ​ 2.数据结构优化

    ​ 3.单调栈、队列优化

    ​ 4.斜率优化

    ​ 5.四边形不等式

    ​ 6.优化枚举顺序

    ​ 7.倍增优化


    一般步骤

    ​ 1.确定一个无后效性、可高效转移的状态

    ​ 2.确定枚举顺序以及初始值

    ​ 3.确定转移方式

    ​ 4.确定答案由哪些状态得来

    ​ 例:0/1背包问题

    ​ 1.设F[i]为包内体积为i时能获得的最大状态

    ​ 2.先遍历每个物品,又由于每个物品只能选一次,所以枚举体积需要倒序枚举

    ​ 3.F[j]这个状态可以由该物品不选到达,也可以由选择该物品到达,也就是F[j] = max(F[j],F[j-v[i]]+w[i]);

    ​ 4.答案是所有状态的最大值


    总结:

    ​ 动态规划一直是算法竞赛中的重点。著名的算法学家、JDOI滴神——QYB曾说过:''想不出来就想动态规划''

    ​ 动态规划的应用十分广泛,但也需要极强的抽象思想,才能设定出高效的状态与转移方程

    ​ 最后,分享一下我特别喜欢的一句话:

    你的一个又一个阶段是由上天安排的,而你,决定的是在这一阶段可以由上一阶段的哪些状态转移而来。越勤奋,越幸运,并不代表这一次你决策的方向有多么优秀,却代表着现在的这一个状态能够续写多少可能的结果
    ——《动态规划》

  • 相关阅读:
    thinkinginjava学习笔记07_多态
    thinkinginjava学习笔记06_复用类
    thinkinginjava学习笔记05_访问权限
    thinkinginjava学习笔记04_初始化与清理
    thinkinginjava学习笔记03_基本语法
    thinkinginjava学习笔记02_对象
    关于药物刺激引起的突变
    通路共出现
    关于reference-free去卷积
    一些研究生期间的反思
  • 原文地址:https://www.cnblogs.com/Marcelo/p/13972454.html
Copyright © 2020-2023  润新知