动态规划(Dynamic Programming)

dp是什么?

  dp是一种编程方法;将一个问题拆成几个子问题,分别求解这些子问题,即可推断出大问题的解。

  • 无后效性

  "未来与过去无关",这就是无后效性。如果给定某一阶段的状态,则在这一阶段以后过程的发展不受这阶段以前各段状态的影响;

  • 有重复的子问题

  子问题会被求解多次;

  • 最优子结构

  大问题的最优解可以由小问题的最优解推出,这个性质叫做“最优子结构性质”;

什么时候可以用dp?

   根据以上三个概念,我们如何判断一个问题能否使用dp解决呢?能将大问题拆成几个小问题,且满足无后效性、最优子结构性质

  • 计数问题:如用n种资源完成某个方法的数量有多少种;
  • 优化:如达成某成目的需要多少钱或者走多少走的问题,这些问题我们在用递归或搜索求解时,因为会枚举所有的可能的路经,当时间复杂度达到如O(2^n)和n的规模很大时,就可以使用dp来进行降维;

dp的通常实现的方法

  • Top-down,记忆化递归,从大到小;例如一开始要求解f(10),那f(10)=f(8)+f(9),求解过的会放到内存里(map,array,list等);
  • Bottom-up,通常意义上我们定义的DP,从小到大;例如要先求解到dp[1],才能求解dp[2],再能求解dp[3];

dp的典型应用

  • Fibonacci sequence
  • LCS:最长公共子序列
  • Knapsack
  • Floyd-Warshall
  • Bellmen-Ford
原文地址:https://www.cnblogs.com/johnnyzhao/p/12935601.html