问题描述
小R近期表现出色,公司决定以股票的形式给予奖励,并允许他在市场上进行交易以最大化收益。给定一个数组,数组中的第 i 个元素代表第 i 天的股票价格。小R需要设计一个算法来实现最大利润。
股票交易规则如下:
- 小R可以多次买卖股票,但在买入新的股票前必须卖出之前的股票。
- 每次卖出股票后存在一天的冷冻期,在冷冻期内小R不能购买股票。
你的任务是帮助小R计算出在遵守交易规则的情况下能够获得的最大利润。
stocks: 一个整数列表,表示连续几天内的股票价格。
测试样例
-
样例1:
输入:
stocks = [1, 2]
输出:1 -
样例2:
输入:
stocks = [2, 1]
输出:0 -
样例3:
输入:
stocks = [1, 2, 3, 0, 2]
输出:3 -
样例4:
输入:
stocks = [2, 3, 4, 5, 6, 7]
输出:5 -
样例5:
输入:
stocks = [1, 6, 2, 7, 13, 2, 8]
输出:12
解题思路
- 由于当前天数的状态与前一天数状态相关,所以采用动态规划
- 状态的表示,采取二维数组dp[i][j],含义为第i天的最大收益,其中j等于2。取值为0或1,其中0代表当前持有股票,1代表当前不持有股票。
- 边界条件的确定,由于涉及到冷冻期,所以需要初始化前两个dp数组
- 状态转移方程,dp[i][0],受到dp[i-1][0]与dp[i-2][1] 与当前股票价格影响。dp[i][1],受到dp[i-1][1]与dp[i-1][0] 与当前股票价格影响。
代码实现
第一步
判断输出长度是否小于2,如果小于则不需要任何处理直接返回0
if len(stocks) < 2 {
return 0
}
第二步
初始化dp数组,确定边界条件。首先dp数组的长度为len(stocks),其中dp[i]的长度为2。0代表持有,1代表不持有。边界条件dp[0][0] = -stocks[0]代表第一天购买股票。dp[0][1] = 0,代表第一天不购买股票。dp[1][0] = bigger(dp[0][0], -stocks[1]),代表第二天存在股票,由于存在冷冻期的关系,所以需要判断第一天购买股票,还是第二天购买股票。dp[1][1] = bigger(stocks[1]+dp[0][0], 0),代表第二天不存在股票。此时有两种情况,保持前一天没有股票的状态,或者是出售前一天存在股票的情况。
dp[0][0], dp[0][1] = -stocks[0], 0
dp[1][0], dp[1][1] = bigger(dp[0][0], -stocks[1]), bigger(stocks[1]+dp[0][0], 0)
第三步
开始遍历整个dp数组确定每一个dp[i][j]的值。dp[i][0]即当前天数持有股票的最大收益该值来源于,前i-1天持有股票继续保持,或者由i-2出售股票后购买当天股票。dp[i][1]即当前天数不持有股票的最大收益该值来源于,前i-1天不持有股票继续保持,或者由i-1持有股票后当天售出。
for i := 2; i < len(stocks); i++ {
dp[i][0] = bigger(dp[i-1][0], dp[i-2][1]-stocks[i])
dp[i][1] = bigger(dp[i-1][1], dp[i-1][0]+stocks[i])
}
第四步返回答案
为实现最大利润所以此时手上一定不会存在股票所以返回dp[len(stocks)-1][1],而不是返回dp[len(stocks)-1][0]
return dp[len(stocks)-1][1]