[LeetCode] 系统刷题5_Dynamic Programming
2019-04-30 00:06 Johnson_强生仔仔 阅读(323) 评论(0) 编辑 收藏 举报Dynamic Programming 实际上是[LeetCode] 系统刷题4_Binary Tree & Divide and Conquer的基础上,加上记忆化的过程。就是说,如果这个题目实际上是类似于Divide and conquer或者说是DFS,但是在计算过程中有很多重复计算同样的过程的话,那么就可以用Dynamic prgramming/记忆化搜索来完成。基本就是利用空间来简化时间复杂度的过程。
可以/很有可能使用Dynamic programming的条件,满足之一即可。
1. Maximum/Minimum
2. Yes/No. True/False
3. Count(*)
一定不是Dynamic programming的条件,满足之一即可。
1. all 具体方案。
2. input是集合或者跟position无关。
3. move 4 directions in 二维数组。(或者说不是固定方向,有可能会有循环)
动态规划4要点:
1. 状态 state
mem[i][j] 代表什么,ex. 代表s1前i个characters和s2前j个characters。
2. Function
mem[i][j] = mem[i - 1][j] if ****
3. Initialize
usually mem[0][0] / mem[i][0]/ mem[0][j]
4. 答案
mem[n]/mem[n - 1]/mem[m][n]
在这里将Dynamic programming分为几类。
1. 矩阵Dynamic programming/Matrix DP
state: mem[i][j] 走到坐标(x, y) 的状态。
[LeetCode] 120. Triangle _Medium tag: Dynamic Programming
[LeetCode] 64. Minimum Path Sum_Medium tag: Dynamic Programming
[LeetCode] 62. Unique Paths_ Medium tag: Dynamic Programming
[LeetCode] 63. Unique Paths II_ Medium tag: Dynamic Programming
[LeetCode] 85. Maximal Rectangle_Hard tag: Dynamic Programming
2. Sequence DP
state: mem[i] 前i个位置
mem 的length 设为n
[LeetCode] 70. Climbing Stairs_ Easy tag: Dynamic Programming
[LeetCode] 55. Jump Game_ Medium tag: Dynamic Programming
[LeetCode] 45. Jump Game II_ Hard tag: Dynamic Programming, Greedy
[LeetCode] 53. Maximum Subarray_Easy tag: Dynamic Programming
[LeetCode] 121. Best Time to Buy and Sell Stock_Easy tag: Dynamic Programming
[LeetCode] 122. Best Time to Buy and Sell Stock II_Easy tag: Dynamic Programming
待整理 ------
1685. Sum of Absolute Differences in a Sorted Array
2008. Maximum Earnings From Taxi
1235. Maximum Profit in Job Scheduling
待整理--------
Greedy
[LeetCode] 55. Jump Game_ Medium tag: Dynamic Programming
待整理 ------
2712. Minimum Cost to Make All Characters Equal
待整理--------
3. 分割DP
state: mem[i] 前i个character 是否可行
mem 的length 设为n + 1,因为要考虑到前0个character,也就是empty string。
[LeetCode] 132. Palindrome Partitioning II_ Hard tag: Dynamic Programming
[LeetCode] 139. Word Break_ Medium tag: Dynamic Programming
[LeetCode] 2334. Subarray With Elements Greater Than Varying Threshold_Hard tag: dp, stack # 如果题目是问maximum subarray size的话
4. Two sequences DP
state: mem[i][j] 表明s1的前i个characters, 配上s2的前j 个characters。
mem 的length 设为(n + 1)* (m + 1),因为要考虑到前0个character,也就是empty string。
需要初始化 mem[i][0], mem[0][j]
[LeetCode] 1143. Longest common subsequences_ Medium tag: Dynamic Programming
[LeetCode] 72. Edit Distance_hard tag: Dynamic Programming
[LeetCode] 115. Distinct Subsequences_ Hard tag: Dynamic Programming
[LeetCode] 97. Interleaving String_ Hard tag: Dynamic Programming
5. 背包 backpack DP
待整理:-----------------------------
2786. Visit Array Positions to Maximize Score
2787. Ways to Express an Integer as Sum of Powers
one sequence dp:
2809. Minimum Time to Make Array Sum At Most x
two sequence dp:
待整理:-----------------------------
1) 经典 01 背包问题 (给nums为物品大小, size为target大小的背包, 要装尽量多的东西)
利用二维dp, dp[len(nums) + 1][target + 1] , all False
# initial
dp[i][0] = True , i = [0, n]
# function
dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i - 1]] if j >= nums[i - 1] else dp[i - 1][j] # dp[i][j] 表示前i个物品中是否能组成size 为j的背包,如果可以为True, 否者为False
不取当前物品 取当前物品
[LeetCode] 416. Partition Equal Subset Sum_Medium tag: backpack
2) 可选无数次的 01 背包问题(给nums为物品大小, size 为target大小的背包,要装尽量少的物品使得size == target)
利用二维dp, dp[len(nums) + 1][target + 1] , all float('inf')
# initial
dp[i][0] = 0 , i = [0, n]
# function
dp[i][j] = min( dp[i - 1][j] , dp[i][j - nums[i - 1]] + 1) if j >= nums[i - 1] else dp[i - 1][j] # dp[i][j] 表示前i个物品中小于size 为j的背包的最大价值之和
不取当前物品 取当前物品 # dp[i][j - nums[i - 1]] + 1 因为可以反复选同样的元素
return dp[n][target] if dp[n][target] < float('inf') else -1
[LeetCode] 322. Coin Change_Medium tag: backpack
3) 可选一次的最大value sum背包问题(size array A, value array V and size of the backpack m)
跟单纯的01 背包其实很像, 利用二维dp, dp[len(A) + 1][target + 1] , all 0
# function
dp[i][j] = max( dp[i - 1][j] , dp[i - 1][j - A[i - 1]] + V[i - 1] ) if j >= A[i - 1] else dp[i - 1][j] # dp[i][j] 表示前i个物品中小于size 为j的背包的最大价值之和
不取当前物品 取当前物品
return dp[n][m]
4) nums中选k个num, 使得sum == target. 可以求a.是否存在, 或者b.方案总数
利用三维数组, dp = [n + 1][k + 1][target + 1]
# initial
a. 是否存在
dp[i][0][0] = True, 其他False
b. 方案总数
dp[i][0][0] = 1, 其他 0
# function
a. 是否存在
dp[i][j][t] = dp[i - 1][j][t] or dp[i - 1][j - 1][t - nums[i - 1]] if t >= nums[i - 1] else dp[i - 1][j][t]
b. 方案总数
dp[i][j][t] = dp[i - 1][j][t] + dp[i - 1][j - 1][t - nums[i - 1]] if t >= nums[i - 1] else dp[i - 1][j][t]
# result
a. 是否存在
return dp[n][k][target]
b. 方案总数
return dp[n][k][target]
6. DP