题目描述

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

通过一段时间的观察,\text{lxhgww}lxhgww 预测到了未来 TT 天内某只股票的走势,第 ii 天的股票买入价为每股 AP_iAPi​,第 ii 天的股票卖出价为每股 BP_iBPi​(数据保证对于每个 ii,都有 AP_i \geq BP_iAPi​≥BPi​),但是每天不能无限制地交易,于是股票交易所规定第 ii 天的一次买入至多只能购买 AS_iASi​ 股,一次卖出至多只能卖出 BS_iBSi​ 股。

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

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

输入输出格式

输入格式:

输入数据第一行包括 33 个整数,分别是 TT,\text{MaxP}MaxP,WW。

接下来 TT 行,第 ii 行代表第 i-1i−1 天的股票走势,每行 44 个整数,分别表示 AP_i,\ BP_i,\ AS_i,\ BS_iAPi​, BPi​, ASi​, BSi​。

输出格式:

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

输入输出样例

输入样例#1: 复制

5 2 0
2 1 1 1
2 1 1 1
3 2 1 1
4 3 1 1
5 4 1 1
输出样例#1: 复制

3

说明

对于 30\%30% 的数据,0\leq W<T\leq 50,1\leq\text{MaxP}\leq500≤W<T≤50,1≤MaxP≤50

对于 50\%50% 的数据,0\leq W<T\leq 2000,1\leq\text{MaxP}\leq500≤W<T≤2000,1≤MaxP≤50

对于 100\%100% 的数据,0\leq W<T\leq 2000,1\leq\text{MaxP}\leq20000≤W<T≤2000,1≤MaxP≤2000

对于所有的数据,1\leq BP_i\leq AP_i\leq 1000,1\leq AS_i,BS_i\leq\text{MaxP}1≤BPi​≤APi​≤1000,1≤ASi​,BSi​≤MaxP

题意:

一共t天,最多可以持有maxp支股票。给定每天股票买入卖出价格和每天的交易限额。问可以最多赚多少钱。

思路:

应该能够想得到这是一个dp。子结构就是前i天能赚取的最多价格,这就是“阶段”,也就是第一维。同时我们还需要记录一下持有的股票数,因为状态转移时,不同的股票数的转移是不同的。

因此,dp[i][j]表示第i天持有j的时候所能赚取的最大值。

对于每一天我们都有三种情况。

1.不买也不卖。 那么转移方程就是

2.买入。买入有分两种情况,一种是之前什么都没有,这j股都是在第i天买的。

  另一种是之前的某一天买了k股,今天买了j-k股。而且题目要求两个交易的日子要间隔w天。

3.卖出。之前的某一天有k股,卖掉了k-j股,第i天剩下j股。

但是我们会发现状态转移的时候如果枚举k,会出现O(n^3)的复杂度,需要进一步优化。

观察状态转移方程我们可以把k合并同类项,比如卖出的式子可以变成

由于max{}中的是一个正数,假设我们设在j时这个值为x,扩展到j+1时,我们只有可能取x或者k=j时的值。他是一个递增的选择。

就可以用单调队列来维护这个值了。

由于卖出是由比j大的k推出的,所以在转移卖出这种情况的时候,j应该是逆序的。

 #include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f const int maxn = ;
int t, maxp, w;
struct node{
int ap, bp, as, bs;
}day[maxn];
int dp[maxn][maxn], que[maxn]; int main()
{
scanf("%d%d%d", &t, &maxp, &w);
memset(dp, -inf, sizeof(dp));
for(int i = ; i <= t; i++){
scanf("%d%d%d%d", &day[i].ap, &day[i].bp, &day[i].as, &day[i].bs);
}
for(int i = ; i <= t; i++){
for(int j = ; j <= day[i].as; j++){
dp[i][j] = -j * day[i].ap;
}
for(int j = ; j <= maxp; j++){
dp[i][j] = max(dp[i][j], dp[i - ][j]);
}
if(i <= w)continue;
int head = , tail = ;
for(int j = ; j <= maxp; j++){
while(dp[i - w - ][que[tail]] + que[tail] * day[i].ap <= dp[i - - w][j] + j * day[i].ap && head <= tail){
tail--;
}
que[++tail] = j;
while(j - que[head] > day[i].as){
head++;
}
dp[i][j] = max(dp[i][j], dp[i - w - ][que[head]] - (j - que[head]) * day[i].ap);
} head = , tail = ;
for(int j = maxp; j >= ; j--){
while(dp[i - w - ][que[tail]] + que[tail] * day[i].bp <= dp[i - - w][j] + j * day[i].bp && head <= tail){
tail--;
}
que[++tail] = j;
while(que[head] - j > day[i].bs){
head++;
}
dp[i][j] = max(dp[i][j], dp[i - - w][que[head]] + (que[head] - j) * day[i].bp);
}
} int ans = -;
for(int j = ; j <= maxp; j++){
ans = max(ans, dp[t][j]);
}
printf("%d\n", ans);
return ;
}

洛谷P2569 股票交易【dp】【单调队列】的更多相关文章

  1. 洛谷P2569 股票交易 [SCOI2010] dp

    正解:dp+单调队列优化 解题报告: 先放个传送门鸭qwq umm首先dp转移挺好想的?就买和不买 f[i][j]表示第i天手上有j的股份的最多钱,转移也很好想?就枚举第1天到第i-w-1天枚举买k股 ...

  2. 【Luogu】P2569股票交易(单调队列优化DP)

    题目链接 首先这题可以肯定的是朴素DP秒出.然后单调队列优化因为没接触过所以不会emmm 而且脑补没补出来 坐等四月省选倒数第一emmm 心态爆炸,偷懒放题解链接 #include<cstdio ...

  3. P2569 [SCOI2010]股票交易 dp 单调队列优化

    LINK:股票交易 题目确实不算难 但是坑点挺多 关于初值的处理问题我就wa了两次. 所以来谢罪. 由于在手中的邮票的数量存在限制 且每次买入卖出也有限制. 必然要多开一维来存每天的邮票数量. 那么容 ...

  4. 洛谷P2569 股票交易

    题目传送门https://www.luogu.org/problemnew/show/P2569 第一眼看题就觉得是个dp ,然后看到2000的范围,hmm大概是个n^2的2维dp 开始设状态,第一维 ...

  5. 洛谷P1776--宝物筛选(单调队列+多重背包)

    https://www.luogu.org/problemnew/show/P1776 单调队列+多重背包的讲解https://www.cnblogs.com/JoeFan/p/4165956.htm ...

  6. 【洛谷】【动态规划+单调队列】P1714 切蛋糕

    [题目描述:] 今天是小Z的生日,同学们为他带来了一块蛋糕.这块蛋糕是一个长方体,被用不同色彩分成了N个相同的小块,每小块都有对应的幸运值. 小Z作为寿星,自然希望吃到的第一块蛋糕的幸运值总和最大,但 ...

  7. 【洛谷】【动态规划+单调队列】P1725 琪露诺

    [题目描述:] 在幻想乡,琪露诺是以笨蛋闻名的冰之妖精. 某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来.但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸.于是琪露诺决定到河 ...

  8. 【BZOJ1855】[Scoi2010]股票交易 DP+单调队列

    [BZOJ1855][Scoi2010]股票交易 Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预 ...

  9. 洛谷luogu3957跳房子(单调队列优化)

    QwQ被普及组的题折磨的死去活来. 硬是卡线段树,没卡过QwQ oi生涯,第一道正经的单调队列dp题 进入正题 题目大意: 其中\(n \le 500000\) 看到这个题的第一感觉就是二分金币数 很 ...

随机推荐

  1. java okhttp发送post请求

    java的httpclient和okhttp请求网络,构造一个基本的post get请求,都比py的requests步骤多很多,也比py的自带包urllib麻烦些. 先封装成get post工具类,工 ...

  2. sql语句 case when then else end 语句实例

    表中有A B C三列,用SQL语句实现:当A列大于B列时选择A列否则选择B列,当B列大于C列时选择B列否则选择C列. ----------------------------------------- ...

  3. PMP模拟考试-1

    1. A manufacturing project has a schedule performance index (SPI) of 0.89 and a cost performance ind ...

  4. Iframe难点备忘

    1 iframe处理session过期,框架页面跳转登录页面的问题 <script language="JavaScript"> if (window != top) ...

  5. 【剑指Offer学习】【面试题23:从上往下打印二叉树】

    题目:从上往下打印出二叉树的每一个结点,同一层的结点依照从左向右的顺序打印. 二叉树结点的定义: public static class BinaryTreeNode { int value; Bin ...

  6. ECharts 3 -- gauge表盘的配置项

    绘制一个简单的表盘图表 在绘图前我们需要为 ECharts 准备一个具备高宽的 DOM 容器. <body> <!-- 为 ECharts 准备一个具备大小(宽高)的 DOM --& ...

  7. scala try monad

    当输入的数据格式不正确时,ActivityData 中会出现 OutofIndex 错误,但更多的时候我们只关心想要的结果而不想了解出现了怎样的错误,然后会写出这样的代码   def parseCSV ...

  8. 海康视频监控---Demo

    1,使用在页面中调用ActiveX控件 <object classid='clsid:E7EF736D-B4E6-4A5A-BA94-732D71107808' codebase='' stan ...

  9. 升级MAC OX上的Python到3.4

    第1步:下载Python3.4 下载地址如下: 下载Mac OS X 64-bit/32-bit installerhttps://www.python.org/downloads/release/p ...

  10. Ubuntu 12.04下安装QQ 2012 Beta3(转)

    Ubuntu 12.04下安装QQ 2012 Beta3   由于wine的发展非常迅速.现在网上的利用老版本的wine来安装QQ2012的教程已经有些过时了.实际上操作起来非常简单: 第一步:Ctr ...