动态规划的套路
视频:https://www.youtube.com/watch?v=FLbqgyJ-70I
课件:https://docs.google.com/presentation/d/1F_Qp3kzw7jZkPpb7ll7J6-02285bCA3Z9nmU1e7a2rk/edit#slide=id.p
学习到1h19m02s
一、动态规划的试用前提
1. 无后效性
- 一旦f(i,j)确定,就不用关心如何计算f(i,j)
- 想要确定f(i,j),只需要知道f(i-1,j)和f(i,j-1)的值。而至于他们如何计算出来,对当前或之后的任何子问题都没有影响
- 过去不依赖将来,将来不影响过去
2. 最优子结构
- f(i,j)定义就已蕴含了最优
- 大问题的最优解可以由若干个小问题的最优解推出。(max,min,sum...)
DP能适用的的问题:能将大问题拆解成几个小问题,且满足无后效性、最优子结构性质。
二、DP套路
1. 时间序列型
给出一个序列,其中每个元素可以认为是一天并且今天的状态只取决于昨天的状态。
套路:
- 定义dp[i][j]:表示第i轮的第j种状态(j=1,2...K)
- 千方百计将dp[i][j]与前一轮的状态dp[i-1][j]产生关系(j=1,2...K)
- 最终的结果是dp[last][j]中的某种aggregation(sum,max,min,...) ,last表示最后一天,最终结果可能是max(dp[i][1],dp[i][2],...,dp[i][K])
代表题目:House Robber、Best time to buy and sell stocks、wiggle subsequence
时间复杂度一般是O(n),如果状态不是很多的话
2. 时间序列加强版
给出一个序列,其中一个元素可以认为是一天,但今天的状态和之前的某一天有关,需要挑选。
套路:
- 定义dp[i]:表示第i轮的状态,一般这个状态要求和元素i直接有关
- 千方百计将dp[i]与之前的状态dp[i']产生关系,(i=1,2,...,i-1)比如(sum,max,min)
- dp[i]肯定不能与大于i的轮次有任何关系,否则违反了dp的无后效性
- 最终的结果是dp[i]中的某一个
时间复杂度一般是O(n*n),需要遍历之前的轮次
3. 双序列型
给出两个序列s和t,对他们搞事情。 Longest Common Subsequences, Shortest Common Supersequence, Edit Distances
套路:
- 定义dp[i][j]:表示针对s[0:i]和t[0:j]的子问题的求解
- 千方百计将dp[i][j]往之前的状态去转移:dp[i-1][j],dp[i][j-1],dp[i-1][j-1]
- 最终的结果是dp[m][n]
三、总结
时间序列类:
套路I: 状态与前一个时间序列的状态有关,可以是一维或者二维DP,第一维表示序列,第二维表示状态数量。
LC 198. House Robber
LC 213. House Robber II
LC 123. Best Time to Buy and Sell Stock III
LC 309. Best Time to Buy and Sell Stock with Cooldown
LC 376. Wiggle Subsequence
LC 276. Paint Fence
LC 487. Max Consecutive Ones II
LC 1186. Maximum Subarray Sum with One Deletion
903.Valid Permutations for DI Sequence
套路II: 状态与前几个序列的状态有关,至少是二维DP,第二个维度表示当前最优与前面哪个状态有关。
LC 300. Longest Increasing Subsequence
LC 368. Largest Divisible Subset
LC 1105. Filling Bookcase Shelves
983.Minimum Cost For Tickets
套路III:状态与两个序列的状态有关,至少是二维DP,两个维度表示两个序列
LC1143: Longest Common Subsequences
LC1092: Shortest Common Supersequences
LC72: Edit Distance
LC97: Interleaving String
LC115. Distinct Subsequences
LC 727.Minimum Window Subsequence
区间类:
套路IV: 状态与之前分割的区间有关,至少二维DP,第二个维度表示前面分割的数量。
LC 1278. Palindrome Partitioning III
LC 813. Largest Sum of Averages
LC 410. Split Array Largest Sum
LC 1335. Minimum Difficulty of a Job Schedule
套路V: 大区间的最优值依赖与小区间状态,至少二维DP,两个维度表示区间[i,j]的最优解
LC 516. Longest Palindromic Subsequence
LC 312. Burst Balloons
LC 375. Guess Number Higher or Lower II
LC 375. Guess Number Higher or Lower II
LC 1246. Palindrome Removal
融合两类的boss题目
LC 1000. Minimum Cost to Merge Stones -> dp[i][j][k]表示将区间[i:j]归并成k堆的最小代价。
套路VI: 背包类, 最少二维dp,前i个物品,代价为j的时候的最优值
LC 494. Target
LC 1049. Last Stone Weight II
LC 474.Ones and Zeroes
LC 879. Profitable Schemes
LC 956. Tallest Billboard
518.Coin Change 2
Others
状态压缩: 状态进行编码作为dp的一个维度来记录状态
LC 691. Stickers to Spell Word
LC 1349. Maximum Students Taking Exam
943.Find the Shortest Superstring
弃坑型: 一眼看不出是DP,状态不好涉及
887.Super Egg Drop
920.Number of Music Playlists