此文是来自 https://leetcode.com/discuss/general-discussion/458695/Dynamic-Programming-Patterns 这位外国网友,本人负责汉化
目录
一、达到目标的最小(最大)路径型问题
此类问题的描述为:给定目标,找到达到目标的最小(最大)成本(cost)/路径(path)/总和 (sum)。
通用模板代码为:
for i in range(1,target+1):
for j in range(len(ways)):# ways:达到目标的方法个数
if ways[i]<=i:
dp[i] = min(dp[i], dp[i - ways[j]] + 代价(cost) / 路径(path) / 总和(sum))
return dp[target]
类似的问题有:
二、不同的方式
此类问题的描述为:给定目标,找到达到目标的不同方式
通用模板代码为:
for i in range(1,target):
for j in range(len(ways)):
if ways[j]<=i:
dp += dp[i-ways[j]]
return dp[target]
类似的问题有:
还有一些问题指出了重复的次数,在这种情况下,还要增加一个循环来模拟每个重复。
- Knight Probability in Chessboard
- Target Sum
- Combination Sum IV
- Knight Dialer
- Dice Roll Simulation
- Partition Equal Subset Sum
- Soup Servings
- Domino and Tromino Tiling
- Minimum Swaps To Make Sequences Increasing
- Number of Longest Increasing Subsequence
- Unique Paths II
- Out of Boundary Paths
- Number of Ways to Stay in the Same Place After Some Steps
- Count Vowels Permutation
三、合并区间
此类问题的描述为:给定一组数字来获得的最佳值,可以从当前数字以及它左侧或者右侧的数字来找到解决问题的方法。
通用模板代码为:
for l in range(1,n):
for i in range(n-l):
j = i+l
for k in range(i,j):
dp[i][j] = max(dp[i][j], dp[i][k] + result[k] + dp[k+1][j])
return dp[0][n-1]
类似的问题有:
- Minimum Cost Tree From Leaf Values
- Unique Binary Search Trees
- Minimum Score Triangulation of Polygon
- Remove Boxes
- Minimum Cost to Merge Stones
- Burst Balloons
- Guess Number Higher or Lower II
四、字符串DP问题
此类问题的描述为:给定两个字符串s1和s2,返回一些结果
通用模板代码为:
/**
i : 字符串s1的下标
j : 字符串s2的下标
**/
for i in range(1,n+1):
for j in range(1,m+1):
if s1[i-1] == s2[j-1]:
dp[i][j] = #code....#
else:
dp[i][j] = #code....#
如果自给一个字符串的话,方法几乎不变:
for l in range(1,n):
for i in range(n-l):
j = i+l
if s[i] == s[j]:
dp[i][j] = /*code*/
else:
dp[i][j] = /*code*/
类似的问题有:
- Longest Common Subsequence
- Palindromic Substrings
- Longest Palindromic Subsequence
- Shortest Common Supersequence
- Edit Distance
- Distinct Subsequences
- Minimum ASCII Delete Sum for Two Strings
- Longest Palindromic Substring
四、做决策问题
问题描述:给定一组值,找到答案,并提供选择或忽略当前值的选项
通用模板代码:
#i: 一组值的下标
#j: 忽略j值的选项
for i in range(1,n):
for j in range(1,k+1):
dp[i][j] = max(dp[i][j], dp[i-1][j] + arr[i], dp[i-1][j-1])
dp[i][j-1] = max(dp[i][j-1], dp[i-1][j-1] + arr[i], arr[i])
类似的问题有:
- House Robber
- Best Time to Buy and Sell Stock
- Best Time to Buy and Sell Stock with Transaction Fee
- Best Time to Buy and Sell Stock with Cooldown
- Best Time to Buy and Sell Stock III
- Best Time to Buy and Sell Stock IV
其实很多问题不用动态规划的方法也可以做出,这里只是把类似问题的解法给总结一下