股票买卖问题:状态定义的误解与思考

问题

股票买卖问题是动态规划中常考的题型,题目一般是给一个 p r i c e s prices prices的数组,每个元素代表当天的股票价格,再给你一个 k k k值,代表允许交易的最大次数,最终让你求出能获得的最大利润。

状态的定义与理解

状态定义

d p [ i ] [ k ] [ s ] dp[i][k][s] dp[i][k][s]

  • i i i:第 i i i天;
  • k k k:交易的最大次数(这里有很多歧义,理解部分重点解释);
  • s s s:持有状态,0代表不持有,1代表持有。

举个例子, d p [ 3 ] [ 1 ] [ 0 ] dp[3][1][0] dp[3][1][0]代表在第三天,我至今最多进行了1次交易,现在没有持有股票的最大利润是多少。

状态转移函数

借用东哥的一个图理解下:

  • d p [ i ] [ k ] [ 0 ] = m a x ( d p [ i − 1 ] [ k ] [ 0 ] , d p [ i − 1 ] [ k ] [ 1 ] + p r i c e s [ i ) dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i) dp[i][k][0]=max(dp[i1][k][0],dp[i1][k][1]+prices[i)
  • 理解:当天不持有的最大利润 = m a x max max(前一天就不持有,前一天持有但是今天卖出了)
  • d p [ i ] [ k ] [ 1 ] = m a x ( d p [ i − 1 ] [ k ] [ 1 ] , d p [ i − 1 ] [ k − 1 ] [ 0 ] − p r i c e s [ i ] ) dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]) dp[i][k][1]=max(dp[i1][k][1],dp[i1][k1][0]prices[i])
  • 理解:当天不持有的最大利润 = m a x max max(前一天就持有,前一天不持有但是今天买入了)

这里有个细节是, k k k是在买入动作进行更新的。如果卖出的时候才更新,会出现超出交易次数的限制。
在这里插入图片描述

困惑

这里我最开始看对 k k k的变化有个疑问:

为什么计算 d p [ i ] [ k ] [ 1 ] dp[i][k][1] dp[i][k][1]的时候,认为前一天不持有的状态是 d p [ i − 1 ] [ k − 1 ] [ 0 ] dp[i-1][k-1][0] dp[i1][k1][0]而不是 d p [ i − 1 ] [ k + 1 ] [ 0 ] dp[i-1][k+1][0] dp[i1][k+1][0]

如果在 i i i天买入后的交易次数上限是 k k k i − 1 i-1 i1天的交易次数上限不应该是 k + 1 k+1 k+1吗,怎么可能是 k − 1 k-1 k1呢?

不得不说这个地方东哥在书里的一句描述给了我很大的误解:
在这里插入图片描述

思考

还是要回到 d p [ i ] [ k ] [ s ] dp[i][k][s] dp[i][k][s]的定义上来,这个 k k k代表的到底是什么?

  • 理解1:按照东哥上面红框这个描述,我本来的理解是:到第 i i i天,我还「剩下的最大交易次数」;❌
  • 理解2:到第k天「已经进行的交易次数」;❌
  • 理解3到第k天为止「最多已经进行的交易次数」!✅ (其实在前文东哥举例子的时候是这么说的,但是后面改了个说法我就晕了…笨笨子)

为什么理解3就是通的呢?还是回到我最初的那个困惑:

为什么计算 d p [ i ] [ k ] [ 1 ] dp[i][k][1] dp[i][k][1]的时候,认为前一天不持有的状态是 d p [ i − 1 ] [ k − 1 ] [ 0 ] dp[i-1][k-1][0] dp[i1][k1][0]而不是 d p [ i − 1 ] [ k + 11 ] [ 0 ] dp[i-1][k+11][0] dp[i1][k+11][0]

你想呀,如果是理解1(剩下的最大交易次数),今天买入交易了一次变成了 k k k,那昨天剩下的次数一定比今天多一次才行,就应该是 d p [ i − 1 ] [ k + 1 ] [ 0 ] dp[i-1][k+1][0] dp[i1][k+1][0]

如果是理解2,状态转移函数和最后的返回值就要大改了,显然不是一个合适的状态定义。

如果是理解3,一切就合乎情理了,本来题目说的也是最多允许交易 k k k次,如果到第 i i i天最多已经进行的交易次数是 k k k,且在第 i i i天我们进行了买入的操作,那么第 i − 1 i-1 i1天当然最多已经进行的交易次数是 k − 1 k-1 k1了。

反思

股票买卖题型我至少刷了3次了,竟然今天才产生这样的疑问,说明之前理解的并不透彻,更多是浮在表面的记忆层面,一味追求提交通过。希望后面的刷题之路中,多一点类似的深度思考,真正弄懂弄透,把刷题变成有趣的事情。
在这里插入图片描述

参考资料

  1. 《labuladong的算法小抄》
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值