代码随想录算法训练营第四十一天 |动态规划part08
121 买卖股票的最佳时机I
思路:两次for循环,dp[i] [j]表示第i天买入第j天卖出所得的利润,代码如下:
prices = [2,1,2,1,0,1,2]
dp = [[0 for i in range(len(prices)+1)] for j in range(len(prices)+1)]
# print(dp)
for i in range(1, len(prices)):
for j in range(i+1, len(prices)+1):
dp[i][j] = prices[j-1] - prices[i-1]
max_ = 0
for i in range(1, len(prices)):
for j in range(i+1, len(prices)+1):
if dp[i][j] > max_:
max_ = dp[i][j]
print(max_)
以上代码是过不去的,因为时间复杂度太高了。
-
确定dp数组以及下标的含义
- dp[i] [0] 持有这支股票的最大金额
- dp[i] [1] 不持有这支股票的最大金额
-
递推公式
- dp[i] [0] = max(dp[i-1] [0] , -price[i]) (第i-1天也有这支股票;第i天买入这支股票)
- dp[i] [1] = max(dp[i-1] [1] , dp[i-1] [0]+price[i]) ((第i-1天也没有这支股票;第i天卖出这支股票,也就是第i-1天有这支股票))
-
dp数组如何初始化
- dp[0] [0] = -price[0]
- dp[0] [1] = 0
-
遍历顺序
- 从前往后打印
-
打印dp数组
- return dp[i-1] [-1]
dp = [[0,0] for i in range(len(prices))]
dp[0][0] = prices[0] * (-1)
dp[0][1] = 0
for i in range(1,len(prices)):
dp[i][0] = max(dp[i-1][0],-prices[i])
dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i])
return dp[-1][1]
122 买卖股票的最佳时机II
思路:和上一题几乎一模一样,不过这一次股票可以买卖多次了,所以
有股票时的最大金额 = max(前一天也有;前一天没有股票,今天买了股票了)
dp[i] [0] = max(dp[i-1] [0] , dp[i-1] [1] - prices[i])
dp = [[0,0] for i in range(len(prices))]
dp[0][0] = -prices[0]
dp[0][1] = 0
for i in range(1,len(prices)):
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[-1][1]
也可以采用贪心的思路:
result = []
for i in range(1,len(prices)):
result.append(prices[i] - prices[i-1])
sum_ = 0
for i in result:
if i > 0 :
sum_ += i
return sum_
123 买卖股票的最佳时机III
这道题一下子就难度上来了,关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。
-
确定dp数组以及下标的含义
- dp[i] [0] 不操作
- dp[i] [1] 第一次持有
- dp[i] [2] 第一次不持有
- dp[i] [3] 第二次持有
- dp[i] [4] 第二次不持有
-
递推公式
- dp[i] [0] = dp[i-1] [0] (可以不操作)
- dp[i] [1] = max(dp[i-1] [1] ,dp[i-1] [0] - prices[i])
- dp[i] [2] = max(dp[i-1] [2] ,dp[i-1] [1] + prices[i])
- dp[i] [3] = max(dp[i-1] [3] ,dp[i-1] [2] - prices[i])
- dp[i] [4] = max(dp[i-1] [4] ,dp[i-1] [3] + prices[i])
-
dp数组如何初始化
- dp[i] [0] = 0
- dp[i] [1] = -prices[0]
- dp[i] [2] = 0
- dp[i] [3] = -prices[0]
- dp[i] [4] = 0
-
遍历顺序
- for i in range(1, len(prices)):
-
打印dp数组
- return dp[-1] [4]
# prices = [7, 6, 4, 3, 1]
dp = [[0] * 5 for i in range(len(prices))]
dp[0][0] = 0
dp[0][1] = -prices[0]
dp[0][2] = 0
dp[0][3] = -prices[0]
dp[0][4] = 0
for i in range(1, len(prices)):
dp[i][0] = dp[i - 1][0]
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])
dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i])
dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i])
dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i])
# print(dp)
return dp[-1][4]