【题目大意】

  已知第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. MySQL备份之mysqlhotcopy与注意事项

    此文章主要向大家介绍的是MySQL备份之mysqlhotcopy与其在实际操作中应注意事项的描述,我们大家都知道实现MySQL数据库备份的常用方法有三个,但是我们今天主要向大家介绍的是其中的一个比较好 ...

  2. Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) D

    D. Bear and Two Paths time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  3. [bzoj 2844]线性基+高斯消元

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2844 又用到线性基+高斯消元的套路题了,因为经过高斯消元以后的线性基有非常好的序关系,所以 ...

  4. 怎么把centos虚拟机zip文件导入vm虚拟机中

    执行以上三步就可以将一个压缩的centoszip文件导入到虚拟机中

  5. kettle基础操作

    ETL:抽取(extract).转换(transform).加载(load)至目的端的过程: Kettle是ETL工具代表之一,是pentaho中的一个数据整合的一个组件.Kettle里包括多个Job ...

  6. [BZOJ2946] [Poi2000]公共串解题报告|后缀数组

    给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 单词个数<=5,每个单词长度<=2000     尽管最近在学的是SAM...但是看到这个题还是忍不住想写SA... (其实是不 ...

  7. python面向对象——类和对象

    一.三大编程范式 编程范式即编程的方法论,标识一种编程风格 三大编程范式: 1.面向过程编程(流水线式) 优点:极大的降低了程序的复杂度 缺点:应用场景固定住了,可扩展性差 2.函数式编程 特点: a ...

  8. git放弃本地commit,未push

    如果不小心commit了一个不应该commit的修改,但是还没有push,想撤销那个commit. 步骤: a) git log:获取commit id: b) git reset --hard co ...

  9. 解析gtest框架运行机制

    前言 Google test是一款开源的白盒单元测试框架,据说目前在Google内部已在几千个项目中应用了基于该框架的白盒测试. 最近的工作是在搞一个基于gtest框架搭建的自动化白盒测试项目,该项目 ...

  10. Android 曲线动画animation,类似加入购物车动画

    按照惯例先放效果图:图中小球做抛物线运动 资源图片 1.首先布局文件activity_main.xml,布局很简单,就一个测试按钮 <RelativeLayout xmlns:android=& ...