动态规划类题目

1. 基础型动态规划

  1. LeetCode 746 使用最小花费爬楼梯

    • 特点:线性DP,每步决策只依赖前两步
    • 状态定义:dp[i]表示到达第i个台阶的最小花费
    • 优化:可以用滚动数组将空间复杂度优化到O(1)
  2. LeetCode 119 杨辉三角形 II

    • 特点:组合数学问题,可以用DP优化
    • 技巧:利用滚动数组优化空间复杂度

2. 决策型动态规划

  1. LeetCode 198 打家劫舍

    • 特点:相邻元素不能同时选择
    • 状态定义:dp[i]表示前i个房屋能偷到的最大金额
    • 状态转移:dp[i] = max(dp[i-1], dp[i-2] + nums[i])
  2. LeetCode 740 删除并获取点数

    • 特点:决策会影响相邻元素,类似打家劫舍
    • 优化:通过计数转化为打家劫舍问题

3. 多维动态规划

  1. LeetCode 2944 购买水果需要的最少金币数
    • 特点:需要考虑多个维度的状态
    • 状态定义:dp[i][free_until]表示考虑到第i个水果时的最小花费
    • 记忆化搜索:使用装饰器优化重复计算

深度优先搜索(DFS)

  1. 深度优先遍历问题
    • 应用:二叉树最大深度
    • 递归实现
    • 时间复杂度:O(n)
    • 空间复杂度:O(h),h为树的高度

解题技巧总结

1. 动态规划问题解题步骤

  1. 定义状态
  2. 写出状态转移方程
  3. 确定初始条件和边界情况
  4. 确定计算顺序
  5. 考虑空间优化

2. 常见优化方法

  1. 滚动数组
  2. 记忆化搜索
  3. 状态压缩
  4. 预处理数据

3. 代码实现要点

  1. 考虑边界情况
  2. 注意数组越界
  3. 善用Python内置函数
  4. 合理使用缓存装饰器

总结

  1. 动态规划是最常见的算法类型,关键在于:

    • 正确定义状态
    • 找出状态间的转移关系
    • 考虑空间优化
  2. 深度优先搜索常用于:

    • 树结构问题
    • 图的遍历
    • 回溯问题
  3. 解题技巧:

    • 先画图分析
    • 考虑特殊情况
    • 寻找问题间的相似性
    • 注意代码的简洁性和可读性