题目

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

通过一段时间的观察,\(\text{lxhgww}\) 预测到了未来 \(T\) 天内某只股票的走势,第 \(i\) 天的股票买入价为每股 \(ap_i\),第 \(i\) 天的股票卖出价为每股 \(bp_i\)(数据保证对于每个 \(i\),都有 \(ap_i \geq bp_i\)),但是每天不能无限制地交易,于是股票交易所规定第 \(i\) 天的一次买入至多只能购买 \(as_i\) 股,一次卖出至多只能卖出 \(bs_i\) 股。

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

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

分析

设 \(f(i,j)\) 代表第 \(i\) 持有 \(j\) 股的最大收益。

\[f(i,j) = \max\left\{ \begin{array}{}
\max_{k = 1}^{as_i} f(i - w - 1,j - k) - ap_i\times k \\
\max_{k = 1}^{bs_i} f(i - w - 1,j + k) + bp_i\times k \\
f(i - 1,j)
\end{array} \right.
\]

很容易得出,该方程的时间复杂度为 \(\Theta (n^3)\)。显然会\(\rm T\)。

以只买入的 \(\max_{k = 1}^{as_i} f(i - w - 1,j - k) - ap_i\times k\) 看,我们发现我们要查询的 \(f\) 总是一段连续的区间,但是若使用单调队列维护 \(f\) ,\(ap_i\times k\) 又很恶心。

但是我们通过观察,对于每个 \(ap_i\times k\) 和 \(bp_i \times k\) 所影响到的要查询的 \(f\) ,若 \(j + 1\) ,则它们都会同时加上 \(ap_i\) 或 \(-bp_i\)。

比如原先的 \(f(i - w - 1, j) - ap_i,\ f(i - w - 1, j - 1) - 2ap_i,\cdots,f(i - w - 1, j + k) - ap_i\times k\)。

当区间右移一次时,它们的影响变成了:$f(i - w - 1, j - 1) - ap_i,\ f(i - w - 1, j - 2) - 2ap_i,\cdots $

所以,当要查询的区间右移一次时,它们的相对大小关系是不会改变的,我们可以对原 \(\rm dp\) 式进行变换来更好的运用这个性质。

以买入为例,\(\max_{k = 1}^{as_i} f(i - w - 1,j - k) - ap_i\times k\),若令 \(p = j - k\),则变为:

\[\begin{array}{}
& \max_{p = j - 1}^{j - as_i} f(i - w - 1,p) - ap_i\times (j - p) \\
= & \max_{p = j - 1}^{j - as_i} ( f(i - w - 1,p) + ap_i\times p ) - ap_i\times j
\end{array}
\]

这么一来,\(f\) 与 \(ap_i\) 就有了一一对应的关系,可以很容易的利用单调队列优化。

同理,卖出也可以这样处理,变式为 \(\max_{p = j + 1}^{j + bs_i} (f(i - w - 1,p) + bp_i\times p) - bp_i\times j\)。

接下来就是常规的单调队列优化,时间复杂度为 \(\Theta (n ^ 2)\)。

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = 2000 + 5, inf = 0x3f3f3f3f;
  4. int f[MAXN][MAXN], ap[MAXN], bp[MAXN], as[MAXN], bs[MAXN], w, t, maxp;
  5. struct monQue {
  6. pair<int, int> data[MAXN];
  7. int head, tail;
  8. void clear() {head = 0, tail = 0;}
  9. bool empty() {return tail <= head;}
  10. void push(pair<int, int> x) {
  11. while(!empty() && data[tail - 1] <= x) tail--;
  12. data[tail++] = x;
  13. }
  14. void pop() {head++;}
  15. pair<int, int> front() {return data[head];}
  16. } sell, buy;
  17. int main() {
  18. memset(f, ~0x3f, sizeof(f));
  19. scanf("%d%d%d", &t, &maxp, &w);
  20. for(int i = 1; i <= t; i++)
  21. scanf("%d%d%d%d", &ap[i], &bp[i], &as[i], &bs[i]);
  22. for(int i = 1; i <= t; i++) {
  23. buy.clear(); sell.clear();
  24. for(int j = 0; j <= maxp; j++) {
  25. f[i][j] = max(f[i - 1][j], f[i][j]);
  26. if(j <= as[i]) f[i][j] = max(-ap[i] * j, f[i][j]);
  27. if(i - w - 1 <= 0) continue;
  28. if(j) {
  29. while(!buy.empty() && buy.front().second < j - as[i]) buy.pop();
  30. buy.push(make_pair(f[i - w - 1][j - 1] + ap[i] * (j - 1), j - 1));
  31. f[i][j] = max(buy.front().first - ap[i] * j, f[i][j]);
  32. }
  33. }
  34. if(i - w - 1 <= 0) continue;
  35. for(int j = maxp - 1; j >= 0; j--) {
  36. while(!sell.empty() && sell.front().second > j + bs[i]) sell.pop();
  37. sell.push(make_pair(f[i - w - 1][j + 1] + bp[i] * (j + 1), j + 1));
  38. f[i][j] = max(sell.front().first - bp[i] * j, f[i][j]);
  39. }
  40. }
  41. int ans = -inf;
  42. for(int i = 0; i <= maxp; i++) {
  43. ans = max(f[t][i], ans);
  44. }
  45. printf("%d\n", ans);
  46. return 0;
  47. }

后记

终于把这个坑填上了。。

【SCOI 2010】股票交易的更多相关文章

  1. [SCOI 2010] 股票交易

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1855 [算法] 单调队列优化动态规划 [代码] #include<bits/s ...

  2. SCOI 2010 连续攻击游戏(贪心,图论)

    SCOI 2010 连续攻击游戏 solution 直接就硬刚 我愿称贪心为暴力 因为题目中要求一定从小到大贪心,那么当前点的下标有能够选取的较大点,那么它一定可以和前面的一个较小点连接,所以可以直接 ...

  3. 【BZOJ 1857】【SCOI 2010】传送带

    三分套三分,虽然简单,但是也得掌握,,, 时间复杂度$O(log_{1.5}^2 n)$ 一开始WA好几次发现是快速读入里没有return,这样也能过样例?_(:3J∠)_ #include<c ...

  4. SCOI 2010 序列操作

    题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b ...

  5. [SCOI 2010]传送带

    Description 题库链接 在一个 \(2\) 维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段 \(AB\) 和线段 \(CD\) .在 \(AB\) 上的移动速度为 ...

  6. [SCOI 2010]字符串

    Description lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数.现在lxhgw ...

  7. 解题:SCOI 2010 序列操作

    题面 线段树......模板题(雾? 然而两种标记会互相影响,必须保证每次只放一个(不然就不知道怎么放了),具体的影响就是: 翻转标记会使得覆盖标记一起翻转,下放的时候就是各种swap 覆盖标记会抹掉 ...

  8. Scoi 2010 幸运数字

    [题目描述]在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸 ...

  9. 【SCOI 2010】传送带

    为了方便,我们不妨设$\rm P \lt Q,R$ 我们发现,有$\rm E$点在$\rm AB$上,$\rm F$点在$\rm CD$上,最优解一定是$\rm AE\rightarrow EF\ri ...

随机推荐

  1. mysql数据库字段类型的选择原则

    原文链接:http://blog.csdn.net/u013412790/article/details/51615407 数据库类型的选择对数据库的性能影响很大 1 . 数据类型会影响存储空间的开销 ...

  2. CentOS-7.3.1611编译安装 Nginx-1.12.1+mysql-5.7.19+PHP-7.1.8+zabbix-3.4.1

    CentOS-7.3.1611编译安装 Nginx-1.12.1+mysql-5.7.19+PHP-7.1.8+zabbix-3.4.1 下载软件 1.下载nginx http://nginx.org ...

  3. Hyper-V 2016 配置管理系列(准备篇)

    2.1 推荐软硬件配置 2.2 Hyper主机前提准备 前提条件: 具有二级地址转换(SLAT)的64位处理器.要安装Hyper-V虚拟化组件(如Windows管理程序),处理器必须具有SLAT 足够 ...

  4. sql server 索引总结三

    一.非聚集索引维护 非聚集索引的行定位器值保持相同的聚集索引值,即使该聚集索引列物理上重新定位后,也是如此. 为了优化这个维护开销,SQL Server添加一个指向旧数据页的指针,以在页面分割之后指向 ...

  5. RF的一些技术知识

    1. dBm 定义的是 miliwatt(毫瓦特).0 dBm=1mw:    dBw 定义 watt.0 dBW = 1 W =1000 mw = 10lg(1000/1)dBm=30dbm. dB ...

  6. LeetCode Minimum Depth of Binary Tree 找最小深度(返回最小深度)

    题意:找到离根结点最近的叶子结点的那一层(设同一层上的结点与根结点的距离相等),返回它所在的层数. 方法有: 1.递归深度搜索 2.层次搜索 方法一:递归(无优化) /** * Definition ...

  7. pat甲级1020中序后序求层序

    1020 Tree Traversals (25)(25 分) Suppose that all the keys in a binary tree are distinct positive int ...

  8. Head First HTML与CSS阅读笔记(二)

    上一篇Head First HTML与CSS阅读笔记(一)中总结了<Head First HTML与CSS>前9章的知识点,本篇则会将剩下的10~15章内容进行总结,具体如下所示. div ...

  9. 基于Dockerfile 构建redis5.0.0(包括持久化)及RedisDestopManager 监控

    一 创建Dockerfile [root@zxmrlc docker]# mkdir redis [root@zxmrlc docker]# cd redis && touch Doc ...

  10. 【洛谷1993】小K的农场(差分约束系统模板题)

    点此看题面 大致题意: 给你若干组不等式,请你判断它们是否有解. 差分约束系统 看到若干组不等式,应该很容易想到差分约束系统吧. \(A-B≥C\):转换可得\(A-B≥C\) \(A-B≤C\):转 ...