最近开始在leetcode刷题,记录一下每日发现。因为自己python也是半吊子水平,权且当顺便学习python了。
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
使用动态规划方法。
这个问题的「状态」有三个,第一个是天数,第二个是允许交易的最大次数,第三个是当前的持有状态(即之前说的 rest 的状态,我们不妨用 1 表示持有,0 表示没有持有)
给予初始条件(base case)和状态转移方程。
#base case:
dp[-1][k][0] = dp[i][0][0] = 0
dp[-1][k][1] = dp[i][0][1] = -infinity
#初始状态转移方程
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], dp[i-1][k-1][0] - prices[i])
在本题中尽可能多即k=inf,所以认为k和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], dp[i-1][k-1][0] - prices[i])
= max(dp[i-1][k][1], dp[i-1][k][0] - prices[i])
#我们发现数组中的 k 已经不会改变了,也就是说不需要记录 k 这个状态了:
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
有了这个思路,我们用数组形式实现动态规划:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n=len(prices)
if n==0:
return 0
dp = [([0] * 2) for i in range(n)]
for i in range(0,n):
dp[i][1]= -float('inf')
dp[-1][1]= -float('inf')
for i in range(0,n):
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
return dp[n-1][0]
来看一个强化版本的股票问题。
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票。
这道题的重点在于无法简化三维数组形式,所以必须穷举所有的可能。
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
if n == 0:
return 0
dp = [[[0 for i in range(2)] for i in range(3)] for i in range(n)]
for k in range(3):
dp[0][k][1] = -float('inf')
dp[-1][k][1] = -float('inf')
print(dp[-1][k][1])
for i in range(0,n):
for k in range(2,0,-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],dp[i-1][k-1][0]-prices[i])
return dp[n-1][2][0]
碰到一个奇怪的错误:
NameError: name ‘inf’ is not defined
解决方案:from numpy import inf
另一种解决方法,使用float(‘inf’)代替inf
如何在python里分配多维数组数组,今天找到一种简明的方法:
dp = [[[0 for i in range(2)] for i in range(3)] for i in range(n)]
以上等于是分配了一个三维数组dp[n][3][2]。