目录

  • ​​动态规划整体思路​​
  • ​​背包问题​​

【Leetcode】python动态规划_python

动态规划整体思路

  1. 思考状态(重点)
    状态的定义,先尝试「题目问什么,就把什么设置为状态」
  2. 思考状态转移方程(核心、难点)
    如果「状态转移方程」不容易得到,尝试修改定义,目的依然是为了方便得到「状态转移方程」。「状态转移方程」是原始问题的不同规模的子问题的联系。即大问题的最优解如何由小问题的最优解得到。常见的推导技巧是:分类讨论。即:对状态空间进行分类;

「动态规划」方法依然是「空间换时间」思想的体现,常见的解决问题的过程很像在「填表」。

  1. 思考初始化
    初始化是非常重要的,初始化状态一定要设置对,才可能得到正确的结果。
  • 角度 1:直接从状态的语义出发;
  • 角度 2:如果状态的语义不好思考,就考虑「状态转移方程」的边界需要什么样初始化的条件;
  • 角度 3:从「状态转移方程」方程的下标看是否需要多设置一行、一列表示「哨兵」(sentinel),这样可以避免一些特殊情况的讨论。
  1. 思考输出
    有些时候是最后一个状态,有些时候可能会综合之前所有计算过的状态。
  2. 思考优化空间(也可以叫做表格复用)
    「优化空间」会使得代码难于理解,且是的「状态」丢失原来的语义,初学的时候可以不一步到位。先把代码写正确是更重要;
    「优化空间」在有一种情况下是很有必要的,那就是状态空间非常庞大的时候(处理海量数据),此时空间不够用,就必须「优化空间」;
    非常经典的「优化空间」的典型问题是「0-1 背包」问题和「完全背包」问题

背包问题

常见的背包问题有:
1、组合问题:
公式:dp[i] += dp[i-num]

  1. 组合总和 Ⅳ
  2. 目标和
  3. 零钱兑换 II

2、True、False问题:(拆分子集)
公式:dp[i] = dp[i] or dp[i-num]

  1. 单词拆分
  2. 分割等和子集

3、最大最小问题:
公式:dp[i] = min(dp[i], dp[i-num]+1)或者dp[i] = max(dp[i], dp[i-num]+1)

  1. 一和零
  2. 零钱兑换

做题步骤:
1.分析是否为背包问题。
2.是以上三种背包问题中的哪一种。
3.是0-1背包问题还是完全背包问题。也就是题目给的nums数组中的元素是否可以重复使用。
4.如果是组合问题,是否需要考虑元素之间的顺序。需要考虑顺序有顺序的解法,不需要考虑顺序又有对应的解法。

背包问题的判定

背包问题具备的特征:给定一个target,target可以是数字也可以是字符串,再给定一个数组nums,nums中装的可能是数字,也可能是字符串,问:能否使用nums中的元素做各种排列组合得到target。

【Leetcode】python动态规划_背包问题_02

背包问题技巧:

  1. 如果是0-1背包,即数组中的元素不可重复使用,nums放在外循环,target在内循环,且内循环倒序;

for num in nums:
for i in range(target, nums-1, -1):

  1. 如果是完全背包,即数组中的元素可重复使用,nums放在外循环,target在内循环。且内循环正序。

for num in nums:
for i in range(nums, target+1):

  1. 如果组合问题需考虑元素之间的顺序,需将target放在外循环,将nums放在内循环。

for i in range(1, target+1):
for num in nums:

参考文章:
​​​大佬的刷题笔记​​​​动态规划背包问题视频教程​