Leetcode刷题第十三天-动态规划

198:打家劫舍

链接:198. 打家劫舍 - 力扣(LeetCode)

线性数组

 1 class Solution:
 2     def rob(self, nums: List[int]) -> int:
 3         #dp[i]偷房间i能获得的最大价值
 4         #推导公式dp[i]=max(dp[i-2]+nums[i],dp[i-1]):dp[i-1]不偷房间i,dp[i-2]+nums[i]偷房间i
 5         #dp数组初始化0号房间最大价值就是nums[0],1号房间最大价值是max(nums[0],num[1])
 6         #遍历顺序:正序
 7         #打印dp数组
 8         n=len(nums)
 9         if(n<=2):   return max(nums)
10         dp=[0]*n 
11         dp[0],dp[1]=nums[0],max(nums[0],nums[1])
12         for i in range(2,n):
13             dp[i]=max(dp[i-2]+nums[i],dp[i-1])
14         return dp[n-1]
rob

213:打家劫舍II

链接:213. 打家劫舍 II - 力扣(LeetCode)

环形数组

 1 class Solution:
 2     def rob(self, nums: List[int]) -> int:
 3         #选首
 4         #选尾
 5         #首尾都不选
 6         #去掉头或者去掉尾就是198打家劫舍,去头去尾取最大值
 7         n=len(nums)
 8         if(n<=3):    return max(nums)
 9         return max(self.rob1(nums[1:]),self.rob1(nums[:n-1]))
10     
11     def rob1(self, nums):
12         n=len(nums)
13         if(n<=2):   return max(nums)
14         dp=[0]*n 
15         dp[0],dp[1]=nums[0],max(nums[0],nums[1])
16         for i in range(2,n):
17             dp[i]=max(dp[i-2]+nums[i],dp[i-1])
18         return dp[n-1]
rob

337:打家劫舍III

链接:337. 打家劫舍 III - 力扣(LeetCode)

二叉树,树形dp,递归+动态规划

 1 # Definition for a binary tree node.
 2 # class TreeNode:
 3 #     def __init__(self, val=0, left=None, right=None):
 4 #         self.val = val
 5 #         self.left = left
 6 #         self.right = right
 7 class Solution:
 8     def rob(self, root: Optional[TreeNode]) -> int:
 9         #dp[0]当前节点偷的最大值,dp[1]当前节点不偷的最大值
10         #推导公式return max(dp)
11         #后序遍历:当前节点偷还是不偷,需要看它的值和它left+right大小,孩子有一个偷,根节点就不能
12         #打印dp数组
13         return max(self.traversal(root))
14     def traversal(self,root):
15         if(not root):   return [0,0]
16         left=self.traversal(root.left)
17         right=self.traversal(root.right)
18         #不偷
19         value1=max(left)+max(right)
20         #
21         value2=root.val+left[0]+right[0]
22         return[value1,value2]
23 
24         
rob

121:买卖股票得最佳时机

链接:121. 买卖股票的最佳时机 - 力扣(LeetCode)

只买卖一次,不重复买卖,股票买入时,手中现金为0

 1 class Solution:
 2     def maxProfit(self, prices: List[int]) -> int:
 3         #dp[i][0]第i天持有股票得最大值,dp[i][1]第i天没有股票得最大值
 4         #推导公式 
 5         #dp[i][0] = max(dp[i - 1][0], -prices[i])
 6         #dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0])
 7         #dp数组初始化dp[0]=0
 8         #遍历顺序:正序
 9         #打印dp数组
10         n=len(prices)
11         dp=[[-prices[0],0]]
12         for i in range(1,n):
13             buy = max(dp[i - 1][0], -prices[i])
14             mai = max(dp[i - 1][1], prices[i] + dp[i - 1][0])
15             dp.append([buy,mai])
16         return max(dp[n-1])
maxProfit

121:买卖股票得最佳时机II

链接:122. 买卖股票的最佳时机 II - 力扣(LeetCode)

买卖多次,股票买入时,手中现金不为0,手中现金数为前一天手中没有股票得现金数

 1 class Solution:
 2     def maxProfit(self, prices: List[int]) -> int:
 3         #动态规划
 4         #dp[i][0]第i天持有股票得最大值,dp[i][1]第i天没有股票得最大值
 5         #推导公式 
 6         #dp[i][0] += max(dp[i - 1][0], dp[i - 1][1]-prices[i])
 7         #dp[i][1] += max(dp[i - 1][1], prices[i] + dp[i - 1][0])
 8         #dp数组初始化dp[0]=0
 9         #遍历顺序:正序
10         #打印dp数组
11         n=len(prices)
12         dp=[[-prices[0],0]]
13         for i in range(1,n): dp.append([0,0])
14         for i in range(1,n):
15             dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]-prices[i])
16             dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0])
17         return max(dp[n-1])
18         '''
19         #贪心
20         if(not prices): return 0
21         money,i=0,0
22         lens=len(prices)
23         for i in range(1,lens):
24             money+=max(0,prices[i]-prices[i-1])
25         return money
26         '''
maxProfit

123:买卖股票得最佳时机III

链接:123. 买卖股票的最佳时机 III - 力扣(LeetCode)

 1 class Solution:
 2     def maxProfit(self, prices: List[int]) -> int:
 3         #dp[0]第一次持有股票得最大值,dp[1]第一次没有股票得最大值,dp[2]第二次持有股票得最大值,dp[3]第一次没有股票得最大值
 4         #推导公式
 5         #dp[0] = max(dp[0], -prices[i])
 6         #dp[1] = max(dp[1], dp[0]+prices[i])
 7         #dp[2] = max(dp[2], dp[1]-prices[i])
 8         #dp[3] = max(dp[3], dp[2]+ prices[i])
 9         #dp数组初始化
10         #遍历顺序:正序
11         #打印dp数组
12         dp=[-prices[0],0,-prices[0],0]
13         print(dp)
14         for i in range(1,len(prices)):
15             dp[0] = max(dp[0], -prices[i])
16             dp[1] = max(dp[1], dp[0]+prices[i])
17             dp[2] = max(dp[2], dp[1]-prices[i])
18             dp[3] = max(dp[3], dp[2]+ prices[i])
19         return dp[3]
maxProfit

188:买卖股票得最佳时机IV

链接:188. 买卖股票的最佳时机 IV - 力扣(LeetCode)

 1 class Solution:
 2     def maxProfit(self, k: int, prices: List[int]) -> int:
 3         #dp[i]偶数天持有股票得最大值,奇数天没有股票得最大值
 4         #推导公式
 5         #买dp[j] = max(dp[j], dp[j-1]-price)
 6         #卖dp[j] = max(dp[j], dp[j-1]+price)
 7         #dp数组初始化
 8         #遍历顺序:正序
 9         #打印dp数组
10         dp=[0]*(2*k+1)
11         for i in range(1,2*k+1,2):  dp[i]=-prices[0]
12         print(dp)
13         for price in prices:
14             for j in range(1,2*k+1):
15                 if(j%2):    dp[j] = max(dp[j], dp[j-1]-price)
16                 else:   dp[j] = max(dp[j], dp[j-1]+price)
17         return dp[2*k]
maxProfit

309:买卖股票得最佳时机含冷冻期

链接:309. 买卖股票的最佳时机含冷冻期 - 力扣(LeetCode)

初始化:dp=[-prices[0],0,0],卖出和冷冻期价值都是0
买入股票得最大价值,dp[1]是前一天卖出(也可能不卖)股票获得最大值,dp[2]前一天是冷冻期时,dp[2]的值为前前一天卖出(也可能不卖)股票获得最大值,这俩取最小值,减去当天的股票数
dp[0] = max(dp[0], min(dp[1],dp[2])-prices[i])
冷冻期,需要再dp[1]之前操作,获取前一天卖出股票的最大值,今天是冷冻期,啥都不干,最大价值肯定是前一天卖出的价值
dp[2] = dp[1]
卖出股票
dp[1] = max(dp[1], dp[0]+prices[i])

 1 class Solution:
 2     def maxProfit(self, prices: List[int]) -> int:
 3         #dp[0]第i天持有股票得最大值,dp[1]第i天没有股票得最大值,dp[2]第i天冷冻期最大值
 4         #推导公式 
 5         #dp[0] = max(dp[0], min(dp[1],dp[2])-prices[i])
 6         #dp[2] = dp[1]( 前一天得dp[1],需要先记录dp[2],然后再计算dp[1])
 7         #dp[1] = max(dp[1], dp[0]+prices[i])
 8         #dp数组初始化dp[0]=0
 9         #遍历顺序:正序
10         #打印dp数组
11         dp=[-prices[0],0,0]
12         for i in range(1,len(prices)):
13             dp[0] = max(dp[0], min(dp[1],dp[2])-prices[i])
14             dp[2] = dp[1]
15             dp[1] = max(dp[1], dp[0]+prices[i])
16         return dp[1]
maxProfit

714:买卖股票得最佳时机含手续费

链接:714. 买卖股票的最佳时机含手续费 - 力扣(LeetCode)

 1 class Solution:
 2     def maxProfit(self, prices: List[int], fee: int) -> int:
 3         #dp[i][0]第i天持有股票得最大值,dp[i][1]第i天没有股票得最大值
 4         #推导公式 
 5         #dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]-prices[i])
 6         #dp[i][1] = max(dp[i - 1][1], dp[i - 1][0]+prices[i]-fee)
 7         #dp数组初始化
 8         #遍历顺序:正序
 9         #打印dp数组
10         dp=[[-prices[0],0]]
11         for i in range(1,len(prices)):
12             buy=max(dp[i - 1][0], dp[i - 1][1]-prices[i])
13             mai=max(dp[i - 1][1], dp[i - 1][0]+prices[i]-fee)
14             dp.append([buy,mai])
15         return dp[len(dp)-1][1]
maxProfit

300:最长递增子序列

链接:300. 最长递增子序列 - 力扣(LeetCode)

 1 class Solution:
 2     def lengthOfLIS(self, nums: List[int]) -> int:
 3         #dp[i]nums中第i号元素的最长递增子序列长度
 4         #推导公式dp[i]=(dp[i-1],dp[i-1]+1)
 5         #dp数组初始化dp[i]=1
 6         #遍历顺序
 7         #打印dp数组
 8         n=len(nums)
 9         dp=[1]*n
10         for i in range(1,n):
11             for j in range(i):
12                 if(nums[i]>nums[j]):    dp[i]=max(dp[i],dp[j]+1)
13         return max(dp)
lengthOfLIS

 

posted @ 2024-02-26 10:00  小小小茹茹  阅读(3)  评论(0编辑  收藏  举报