做题笔记:股票市场交易的策略优化 | 豆包MarsCode AI刷题

82 阅读3分钟

问题描述

小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]