概述
动态规划的本质是填表,自底向上的完成DP数组的构建。难点在于DP数组的定义以及状态转移方程的构建。
一维DP
最长公共子串
class Solution:
def LCS(self , str1: str, str2: str) -> str:
#让str1为较长的字符串
if len(str1) < len(str2):
str1, str2 = str2, str1
res = ''
max_len = 0
#遍历str1的长度
for i in range(len(str1)):
#查找是否存在
if str1[i - max_len : i + 1] in str2:
res = str1[i - max_len : i + 1]
max_len += 1
return res
换零钱
class Solution:
def minMoney(self , arr: List[int], aim: int) -> int:
# write code here
if len(arr)==0:
return -1
if aim==0:
return 0
pd=[aim+1]*(aim+1)
pd[0]=0
for i in range(len(pd)):
for j in arr:
if i-j<0:
continue
pd[i]=min(pd[i],pd[i-j]+1)
if pd[aim]==aim+1:
return -1
else:
return pd[aim]
最长上升子序列
class Solution:
def LIS(self , arr: List[int]) -> int:
# write code here
dp=[0]*len(arr)
max1=0
for i in range(len(dp)):
max2=0
for j in range(i):
if arr[j]<=arr[i]:
max2=max(max2,dp[j])
dp[i]=max2+1
max1=max(max1,dp[i])
return max1
打家劫舍系列
class Solution:
def rob(self , nums: List[int]) -> int:
# write code here
res1=0
res2=0
dp=[0]*(len(nums)-1)
# 不偷最后一家,
dp[0]=nums[0]
dp[1]=max(nums[0],nums[1])
for i in range(2,len(dp)):
dp[i]=max(dp[i-1],dp[i-2]+nums[i])
res1=dp[-1]
# 偷最后一家,即不偷第一家和倒数第二家
dp[0]=nums[1]
dp[1]=max(nums[1],nums[2])
for i in range(2,len(dp)):
dp[i]=max(dp[i-1],dp[i-2]+nums[i+1])
res2=dp[-3]+nums[-1]
return max(res1,res2)
二维DP
矩阵最小路径和
class Solution:
def minPathSum(self , matrix: List[List[int]]) -> int:
# write code here
m=len(matrix)
n=len(matrix[0])
dp=[[0]*n for i in range(m)]
dp[0][0]=matrix[0][0]
for i in range(1,n):
dp[0][i]=dp[0][i-1]+matrix[0][i]
for i in range(1,m):
dp[i][0]=dp[i-1][0]+matrix[i][0]
for i in range(1,m):
for j in range(1,n):
dp[i][j]=min(dp[i][j-1],dp[i-1][j])+matrix[i][j]
return dp[-1][-1]
编辑距离
class Solution:
def editDistance(self , str1: str, str2: str) -> int:
# write code here
m=len(str1)+1
n=len(str2)+1
# dp[i][j]str1[0...i],str2[0....j]的最小编辑距离
dp=[[0]*n for i in range(m)]
for i in range(1,n):
dp[0][i]=i
for i in range(1,m):
dp[i][0]=i
for i in range(1,m):
for j in range(1,n):
if str1[i-1]==str2[j-1]:
dp[i][j]=dp[i-1][j-1]
else:
dp[i][j]=min(
dp[i-1][j]+1,
dp[i][j-1]+1,
dp[i-1][j-1]+1
)
return dp[-1][-1]
三维DP
股票买卖
dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])
#max( 今天选择 rest, 今天选择 buy )
dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])
#max( 今天选择 rest, 今天选择 sell )
这里着重提醒一下,时刻牢记「状态」的定义,状态 k 的定义并不是「已进行的交易次数」,而是「最大交易次数的上限限制」。如果确定今天进行一次交易,且要保证截至今天最大交易次数上限为 k,那么昨天的最大交易次数上限必须是 k - 1。
class Solution:
def maxProfit(self , prices: List[int]) -> int:
# write code here
max_k=2
dp=[[[0]*(2) for i in range(3)] for i in range(len(prices))]
dp[0][2][1]=-prices[0]
dp[0][1][1]=-prices[0]
for i in range(1,len(prices)):
for k in range(1,max_k+1):
dp[i][k][0]=max(dp[i-1][k][0],dp[i-1][k][1]+prices[i])
dp[i][k][1]=max(dp[i-1][k-1][0]-prices[i],dp[i-1][k][1])
return dp[-1][max_k][0]
最后
以上就是大意电话为你收集整理的动态规划做题总结一维DP二维DP三维DP的全部内容,希望文章能够帮你解决动态规划做题总结一维DP二维DP三维DP所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复