动态规划之股票类问题--一个通用方法团灭6道题

本文介绍了股票类问题的动态规划通用框架,包括穷举和状态转移方法,适用于多种交易限制条件,如交易次数限制、冷冻期和手续费等。通过分析不同题目,如买卖股票的最佳时机等,展示如何运用同一框架解决这些问题。
摘要由CSDN通过智能技术生成

目录

一:股票类通用框架介绍

一:前言

二:穷举框架

三:状态转移框架

四.注意事项

五.总结

二:实战题目

题目一:买卖股票的最佳时机 (k =1)

题目二:买卖股票的最佳时机2 (k =正无穷大)

题目三:买卖股票的最佳时机3 (k = 2)

题目四:买卖股票的最佳时机3 (k = 任意整数)

第五题:最佳买卖股票时机含冷冻期

题目六:买卖股票的最佳时机含手续费


一:股票类通用框架介绍

一:前言

股票买卖问题是有共性的,我们先对第四题(限制最大交易次数为k)的分析一道一道解决。

因为第四题(限制最大交易次数为k)是最泛化的形式,其它问题都是这个形式的简化。

第一题:只进行一次交易,相当于k = 1;

第二题:不限交易次数,相当于k = 正无穷

第三题:只进行2次交易,相当于k = 2;

第五题和第六题:不限次数,增加六交易冷冻期和手续费的额外条件。

二:穷举框架

对于股票问题,我们不用递归思想进行穷举,而是利用状态进行穷举。

我们具体到每一天,看总共有几种可能的状态,再找出每个状态对应的选择。

我们穷举所有的状态,穷举的目的是根据对应的选择更新状态。

框架代码流程图:

for 状态1 in 状态1的所有取值:
    for 状态2  in  状态2的所有取值:
       for ...
          dp[状态1][状态2][...] = 择优(选择1,选择2,...)

股票问题,每天都有三种选择:买入,卖出,无操作,我们用buy,sell, rest表示这三种选择。

但问题是,并不是每天都可以任意选择这三种选择的,因为sell必须在buy之后,buy必须在sell之后。

那么rest操作还应该分两种状态,一种是buy之后的rest(持有股票),一种是sell之后的rest(此时没有持有股票)。

注意,我们还有交易次数k的限制。就是说你buy还只能在k >0 的前提下操作。

    上面这么多都是为了进行穷举。股票问题的变量有三个:第一个是天数,第二个是允许交易的最大次数,

第三个是当前的持有状态(一般1表示持有,0表示没有持有)。我们使用一个三维数组装下这几种状态的全部组合。

dp[i][k][0 or 1]
0 <= i <= n-1, 1 <= k <= K
n为天数,K为最多交易数
此问题共n * K * 2种状态,全部穷举就能够搞定
for 0 <= i <= n:
    for 1 <= k <= K:
        for s in {0,1}:
            dp[i][k][s] = max{buy , sell , rest}

我们最后想求的答案是dp[n-1][K][0],即最后一天,最多允许k次交易,最多获得多少利润。

三:状态转移框架

上面完成了状态的穷举,我们思考每种状态有哪些选择,应该如何更新状态,只看持有状态,

画出状态转移图。

通过状态转移图,我们可以很清楚看到,每种状态(0和1)是如何转移而来的,

依据这个图,我们来写一下状态转移方程1

dp[i][k][0] = max(dp[i-1][k][0] , dp[i-1][k][1] + price[i])

即 max(选择rest,  选择sell)

状态转移方程解释: 今天我没有持有股票,有两种原因:

1)昨天就没有持有,今天选择rest,所以今天还是没有持有;

2)昨天持有股票,但是sell了,所以今天没有持有股票。

状态转移方程2:

dp[i][k][1] = max(dp[i-1][k][1] , dp[i-1][k-1][0] - price[i])

即 max(选择rest , 选择buy)

状态转移方程解释:

今天我持有股票,有两种可能:

1)要么我昨天就持有股票,然后今天选择rest;

2)要么昨天本就没有持有股票,但是今天选择buy。

四.注意事项

利润变化和k值改动

如果buy,就要从利润中减去price[i],如果sell,就要给利润增加prices[i].

今天的最大利润就是这两种可能选择较大的那个。而且注意k的限制,

我们在选择buy的时候,把k减少了1,因此sell的时候对k就不需要再次改动了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值