知识点:数组操作
类似题目:
901 股票价格跨度 3 31.4% 中等
121 买卖股票的最佳时机 46 50.4% 简单
122 买卖股票的最佳时机 II 43 55.0% 简单
123 买卖股票的最佳时机 III 17 39.0% 困难
309 最佳买卖股票时机含冷冻期 13 49.3% 中等
188 买卖股票的最佳时机 IV 8 28.0% 困难
714 买卖股票的最佳时机含手续费 6 54.5% 中等
502 IPO 6 35.4% 困难
以【leetcode123】举例,使用以下方法一招通吃,困难变easy(OVO)
思路:
设置两维dp,dp[n][4],四个值分别表示:
0:买入第一个股票,第0时初始化为股票的价格的负数
1:卖出第一个股票,第0时不能卖出,所以初始化为0
2:买入第二个股票,第0时初始化为股票的价格的负数,因为最多买两次,可以只买一次,所以在第0时也要初始化
3:卖出第二个股票,第0时不能卖出,所以初始化为0
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if not prices:
return 0
dp = [[float('-inf')] * 4 for _ in range(len(prices))]
dp[0] = [-1 * prices[0], 0, -1 * prices[0], 0]
for i in range(1, len(prices)):
dp[i][0] = max(0 - prices[i], dp[i-1][0])
dp[i][1] = max(dp[i-1][0] + prices[i], dp[i-1][1])
dp[i][2] = max(dp[i-1][1] - prices[i], dp[i-1][2])
dp[i][3] = max(dp[i-1][2] + prices[i], dp[i-1][3])
# print(dp)
return max(dp[-1])
【leetcode502】股票问题变种
使用DP可以解决,但在最后一个用例会出现超出内存与超时问题,超出内存使用滚动数组,超时问题暂未解决
NOTE:本题不再有时间序列,所以要对两个输入列表按照启动资金x[1]从低到高排序,x[0]是否排序都可以
zipa = zip(Profits, Capital)
zipa.sort(key = lambda x: [x[1], -x[0]])
k = min(k, len(zipa))
dp = [[W] + [float('-inf')] * k for _ in range(2)]
dp[0] = [W] * (k+1)
for i in range(1, len(zipa) + 1):
for ki in range(1, k+1):
if dp[(i-1) % 2][ki-1] >= zipa[i-1][1]:
dp[i % 2][ki] = max(dp[(i-1) % 2][ki], dp[(i-1) % 2][ki-1] + zipa[i-1][0])
else:
dp[i % 2][ki] = dp[(i-1) % 2][ki]
# print(dp)
return max(max(dp))
另外leetcode一篇题解:
和本文思想差不多。还没有仔细阅读,先记录在这儿:
本文来自程序媛驿站,未经授权不得转载.
如有需要请公众号后台联系
(欢迎转发到朋友圈~)