【题目大意】

  已知第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每个i,都有APi>=BPi),第i天的一次买入至多只能购买ASi股,一次卖出至多只能卖出BSi股。 股票交易所规定在两次交易(某一天的买入或者卖出均算是一次交易)之间,至少要间隔W天,也就是说如果在第i天发生了交易,那么从第i+1天到第i+W天,均不能发生交易。同时,在任何时间,一个人的手里的股票数不能超过MaxP。 在第1天之前,有一大笔钱(可以认为钱的数目无限),没有任何股票,求T天之后最多赚到多少钱?

【思路】

f[i][j]表示表示到第i个交易日手中持有至多j股时的最大收益。

1、从前一天不买不卖:f[i][j]=max(f[i-1][j],f[i][j])

2、从i-W-1天买股:f[i][j]=max(f[i-W-1][k]-(j-k)*AP[i],f[i][j])

  f[i][j]=max(f[i-W-1][k]+k*AP[i])-j*AP[i]

   令g[i-W-1][k]=f[i-W-1][k]+k*AP[i] → f[i][j]=max(g[i-W-1][k]) - j*AP[i]

3、从i-W-1天卖股:f[i][j]=max(f[i-W-1][k]+(k-j)*BP[i],f[i][j])

  f[i][j]=max(f[i-W-1][k]+k*BP[i])-j*BP[i]。

令g'[i-W-1][k]=f[i-W-1][k]+k*BP[i] → f[i][j]=max(g'[i-W-1][k]) - j*BP[i]

由于对于g[i-W-1][j]与g'[i-W-1][j]均满足:若j1>j2且g[i-W-1][j1]>g[i-W-1][j2],则不必保留g[i-W-1][j2]。所以可以用单调队列来进行优化。

#关于初始化#f[0][0]=0,对于1~W+1天,仅存在买入操作,初始值为-AP[i]*j。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define pre i-W-1
#define INF 0x7fffffff
using namespace std;
const int MAXN=+;
struct node
{
int f,pos;
};
int T,MaxP,W;
int AP[MAXN],BP[MAXN],AS[MAXN],BS[MAXN];
int f[MAXN][MAXN];//表示到第i个交易日手中持有j股时的最大收益
node q[MAXN]; void init()
{
scanf("%d%d%d",&T,&MaxP,&W);
for (int i=;i<=T;i++) scanf("%d%d%d%d",&AP[i],&BP[i],&AS[i],&BS[i]);
} void dp()
{
memset(f,,sizeof(f));
for(int i=;i<=W+;i++)
{
for(int j=;j<=(min(MaxP,AS[i]));j++)
f[i][j]=-AP[i]*j;//表示前(w+1)天仅有可能进行买入操作
}
f[][]=;
for (int i=;i<=T;i++)
{
for (int j=;j<=MaxP;j++) f[i][j]=max(f[i][j],f[i-][j]);
if (pre>)
{
int head=,tail=;
for (int j=;j<=MaxP;j++)
{
int nowf=f[pre][j]+AP[i]*j;
while (head<tail && q[tail-].f<nowf) tail--;
q[tail++]=(node){nowf,j};
while (head<tail && q[head].pos<j-AS[i]) head++;
f[i][j]=max(f[i][j],q[head].f-AP[i]*j);
} head=,tail=;
for (int j=MaxP;j>=;j--)
{
int nowf=f[pre][j]+BP[i]*j;
while (head<tail && q[tail-].f<nowf) tail--;
q[tail++]=(node){nowf,j};
while (head<tail && q[head].pos>j+BS[i]) head++;
f[i][j]=max(f[i][j],q[head].f-BP[i]*j);
}
}
}
} void getans()
{
int ans=-INF;
for (int i=;i<=MaxP;i++) ans=max(ans,f[T][i]);
printf("%d\n",ans);
} int main()
{
init();
dp();
getans();
return ;
}

【单调队列优化DP】BZOJ1855-[Scoi2010]股票交易的更多相关文章

  1. 【bzoj1855】 [Scoi2010]股票交易 单调队列优化DP

    上一篇blog已经讲了单调队列与单调栈的用法,本篇将讲述如何借助单调队列优化dp. 我先丢一道题:bzoj1855 此题不难想出O(n^4)做法,我们用f[i][j]表示第i天手中持有j只股票时,所赚 ...

  2. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

  3. 2018.09.10 bzoj1855: [Scoi2010]股票交易(单调队列优化dp)

    传送门 单调队列优化dp好题. 有一个很明显的状态设置是f[i][j]表示前i天完剩下了j分股票的最优值. 显然f[i][j]可以从f[i-w-1][k]转移过来. 方程很好推啊. 对于j<kj ...

  4. bzoj1855: [Scoi2010]股票交易 单调队列优化dp ||HDU 3401

    这道题就是典型的单调队列优化dp了 很明显状态转移的方式有三种 1.前一天不买不卖: dp[i][j]=max(dp[i-1][j],dp[i][j]) 2.前i-W-1天买进一些股: dp[i][j ...

  5. 1855: [Scoi2010]股票交易[单调队列优化DP]

    1855: [Scoi2010]股票交易 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1083  Solved: 519[Submit][Status] ...

  6. SCOI 股票交易 单调队列优化dp

    这道题 我很蒙.....首先依照搞单调队列优化dp的一般思路 先写出状态转移方程 在想法子去优化 这个题目中说道w就是这一天要是进行操作就是从前w-1天转移而来因为之前的w天不允许有操作!就是与这些天 ...

  7. 动态规划专题(四)——单调队列优化DP

    前言 单调队列优化\(DP\)应该还算是比较简单容易理解的吧,像它的升级版斜率优化\(DP\)就显得复杂了许多. 基本式子 单调队列优化\(DP\)的一般式子其实也非常简单: \[f_i=max_{j ...

  8. 「学习笔记」单调队列优化dp

    目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...

  9. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

随机推荐

  1. POJ - 1017 贪心训练

    Packets Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 59725   Accepted: 20273 Descrip ...

  2. C++构造函数重载以及默认参数引起的二义性

    大家都知道当我们声明一个类时,系统会提供一个默认构造函数.当我们需要提供参数进行对类数据成员进行初始化时,就需要对类的带参构造函数进行重载.同时,如果我们需要调用默认构造函数进行类数据成员的初始化时, ...

  3. 【Foreign】阅读 [线段树][DP]

    阅读 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 0 10 4 10 2 3 10 8 ...

  4. [POJ1637]混合图的欧拉回路判定|网络流

    混合图的欧拉回路判定 上一篇正好分别讲了有向图和无向图的欧拉回路判定方法 如果遇上了混合图要怎么做呢? 首先我们思考有向图的判定方法:所有点的出度=入度 我们可以先为无向边任意定一个向,算出此时所有顶 ...

  5. DP+贪心水题合集_C++

    本文含有原创题,涉及版权利益问题,严禁转载,违者追究法律责任 本次是最后一篇免费的考试题解,以后的考试题目以及题解将会以付费的方式阅读,题目质量可以拿本次作为参考 本来半个月前就已经搞得差不多了,然后 ...

  6. pycharm配置教程

    http://blog.csdn.net/u013088062/article/details/50100121

  7. 【C语言】++(a++)的写法是错的

    http://bbs.csdn.net/topics/390764053 a++得到的是一个右值,++操作需要的是一个左值. ------------------------------------- ...

  8. selenium 操作cookie (cookie测试)

    前言 在实际的web应用中,可能会涉及到cookie测试,验证浏览器中的cookie是否正确..Cookies 验证:如果系统使用了cookie,测试人员需要对它们进行检测.如果在 cookies 中 ...

  9. 从事前端开发必须要了解的CSS原理

    从事Web前端开发的人都与CSS打交道很多,有的人也许不知道CSS是怎么去工作的,写出来的CSS浏览器是怎么样去解析的呢?当这个成为我们提高CSS水平的一个瓶颈时,是否应该多了解一下呢? 一.浏览器的 ...

  10. Android xmlpull 方式解析xml文件

    1.新建一个xml文件,放在res/xml目录下 <?xml version="1.0" encoding="utf-8"?> <citys& ...