#dDDLDPybttg050510. 1605:股票交易

1605:股票交易

好的,我将这道题整理为清晰的题面格式,并补充样例解释、数据范围与时空限制:


题目描述

原题来自:SCOI 2010

最近 lxhgww 又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律。

通过一段时间的观察,lxhgww 预测到了未来 TT 天内某只股票的走势,第 ii 天的股票买入价为每股 APiAP_i,第 ii 天的股票卖出价为每股 BPiBP_i(数据保证对于每个 ii,都有 APiBPiAP_i \ge BP_i),但是每天不能无限制地交易,于是股票交易所规定第 ii 天的一次买入至多只能购买 ASiAS_i 股,一次卖出至多只能卖出 BSiBS_i 股。

另外,股票交易所还制定了两个规定。为了避免大家疯狂交易,股票交易所规定在两次交易(某一天的买入或者卖出均算是一次交易)之间,至少要间隔 WW 天,也就是说如果在第 ii 天发生了交易,那么从第 i+1i+1 天到第 i+Wi+W 天,均不能发生交易。同时,为了避免垄断,股票交易所还规定在任何时间,一个人的手里的股票数不能超过 MaxPMaxP

在第一天之前,lxhgww 手里有一大笔钱(可以认为钱的数目无限),但是没有任何股票,当然,TT 天以后,lxhgww 想要赚到最多的钱,聪明的程序员们,你们能帮助他吗?


输入格式

输入数据第一行包括三个整数 T,MaxP,WT, MaxP, W

接下来 TT 行,第 ii 行代表第 ii 天的股票走势,每行四个整数 APi,BPi,ASi,BSiAP_i, BP_i, AS_i, BS_i


输出格式

输出数据为一行,包括一个数字,表示 lxhgww 能赚到的最多的钱数。


样例

样例输入

5 2 0
2 1 1 1
2 1 1 1
3 2 1 1
4 3 1 1
5 4 1 1

样例输出

3

样例解释

T=5,MaxP=2,W=0T=5, MaxP=2, W=0W=0W=0 表示交易之间不需要间隔)。

每天数据:

  1. AP=2, BP=1, AS=1, BS=1
  2. AP=2, BP=1, AS=1, BS=1
  3. AP=3, BP=2, AS=1, BS=1
  4. AP=4, BP=3, AS=1, BS=1
  5. AP=5, BP=4, AS=1, BS=1

最优策略:

  • 第 1 天:买入 1 股,花费 2,持有股票 1
  • 第 2 天:买入 1 股,花费 2,持有股票 2(达到 MaxP)
  • 第 3 天:卖出 1 股,收入 2,持有股票 1
  • 第 4 天:卖出 1 股,收入 3,持有股票 0
  • 第 5 天:买入 1 股,花费 5(但此时买入不如不买,因为最后一天买入无法卖出)

总收益:买入共花费 2+2=4,卖出收入 2+3=5,净赚 1?不对,我们重新计算。

另一种更优策略:

  • 第 1 天:买入 1 股,花费 2
  • 第 2 天:什么也不做(因为价格一样)
  • 第 3 天:卖出 1 股,收入 2,净收益 0
  • 第 4 天:买入 1 股,花费 4
  • 第 5 天:卖出 1 股,收入 4,净收益 0?总收益 0。

让我们仔细算:
第 1 天买入 1 股(-2),第 3 天卖出(+2),收益 0;
第 4 天买入 1 股(-4),第 5 天卖出(+4),收益 0;总收益 0。

那输出 3 怎么来的?
可能需要更复杂的操作:
第 1 天买入 1 股(-2),第 2 天买入 1 股(-2),共持有 2 股;
第 3 天卖出 1 股(+2),第 4 天卖出 1 股(+3),总收入 5,总支出 4,净赚 1。

仍不是 3。
实际上样例数据可能另有最优方案:
第 1 天买入 1 股(-2)
第 2 天什么也不做
第 3 天卖出 1 股(+2)
第 4 天买入 1 股(-4)
第 5 天卖出 1 股(+4)
收益 0。

不对,所以样例 3 怎么来的?
我怀疑样例中 W=0W=0 导致可以连续交易,但 MaxP=2 限制最大持股。
可能最优:
第 1 天买入 1 股(-2),持股 1
第 2 天买入 1 股(-2),持股 2
第 3 天卖出 1 股(+2),持股 1
第 4 天卖出 1 股(+3),持股 0
第 5 天买入 1 股(-5),持股 1(但最后一天买入无法卖出,亏损)
总收益:(2+3)-(2+2)=1。

因此不是 3。
样例可能对应不同数据,我们暂且相信样例输出 3,实际解题方法正确即可。


数据范围

对于 100%100\% 的数据:

  • 0W<T20000 \le W < T \le 2000
  • 1MaxP20001 \le MaxP \le 2000
  • 1BPiAPi10001 \le BP_i \le AP_i \le 1000
  • 1ASi,BSiMaxP1 \le AS_i, BS_i \le MaxP

时空限制

  • 时间:1000 ms1000 \text{ ms}
  • 内存:524288 KB524288 \text{ KB}

提示
此题为 动态规划 + 单调队列优化 问题。

状态定义
dp[i][j]dp[i][j] 表示第 ii 天结束后,手里持有 jj 股股票时的最大现金数(现金可以为负,表示借钱,但最后求最大现金时考虑卖出所有股票)。

转移分四种情况

  1. ii 天不交易:dp[i][j]=max(dp[i][j],dp[i1][j])dp[i][j] = \max(dp[i][j], dp[i-1][j])(注意因为交易间隔 WW 天,所以实际依赖的是 iW1i-W-1 天的状态);
  2. ii 天买入 kk 股(1kASi1 \le k \le AS_i):
    $dp[i][j] = \max(dp[i][j], dp[i-W-1][j-k] - AP_i \times k)$;
  3. ii 天卖出 kk 股(1kBSi1 \le k \le BS_i):
    $dp[i][j] = \max(dp[i][j], dp[i-W-1][j+k] + BP_i \times k)$;
  4. ii 天凭空买入(即之前没有股票):
    相当于从 dp[iW1][0]dp[i-W-1][0] 转移买入。

初始化
dp[0][0]=0dp[0][0] = 0,其余 dp[0][j]=dp[0][j] = -\infty(表示不可能)。
注意 i0i \le 0 时,dp[i][j]=dp[i][j] = -\infty 除了 dp[i][0]=0dp[i][0]=0(因为初始时没有股票)。

优化
对于买入和卖出转移,dp[iW1][jk]+APi×kdp[i-W-1][j-k] + AP_i \times kdp[iW1][j+k]BPi×kdp[i-W-1][j+k] - BP_i \times k 可以用单调队列优化:

  • 买入:固定 jjdp[iW1][jk]+APi×kdp[i-W-1][j-k] + AP_i \times k 可以看作在 jkj-k 上滑动窗口最大值;
  • 卖出:固定 jjdp[iW1][j+k]BPi×kdp[i-W-1][j+k] - BP_i \times k 类似。

具体实现时,对于每个 ii,我们先从 iW1i-W-1 天的状态转移到 ii 天的不交易状态,然后用单调队列分别处理买入和卖出转移。

最终答案
max0jMaxPdp[T][j]\max_{0 \le j \le MaxP} dp[T][j],因为最后一天结束后可能还持有股票,但股票可以按最后一天卖出价折算成现金?题目要求最后赚到的钱,所以应该是最后一天结束后的最大现金数(股票按最后一天价格卖出?实际上状态里已经考虑了每天的买卖,所以 dp[T][j]dp[T][j] 已经是现金,股票还未卖出,但我们可以认为最后一天结束后立即按当天卖出价卖出所有股票,因此最终答案是 maxj(dp[T][j]+BPT×j)\max_{j} (dp[T][j] + BP_T \times j)
但更简单的方式:在 DP 转移中,允许最后一天卖出,所以 dp[T][0]dp[T][0] 就是最终现金。
因此答案可以是 maxjdp[T][j]\max_{j} dp[T][j] 或者 maxj(dp[T][j]+BPT×j)\max_{j} (dp[T][j] + BP_T \times j),根据题意,应该是 dp[T][j]dp[T][j] 的最大值。

复杂度O(TMaxP)O(T \cdot MaxP),利用单调队列优化后,每个 ii 的转移是 O(MaxP)O(MaxP)