题目链接

BZOJ1855

题解

设\(f[i][j]\)表示第\(i\)天结束时拥有\(j\)张股票时的最大收益

若\(i \le W\),显然在这之前不可能有交易

\[f[i][j] = max\{f[i - 1][j],-ap[i] * j\} \quad [j \le as[i]]
\]

否则,就有三种选择:

①购买

\[f[i][j] = max\{f[i - W - 1][k] - ap[i] * (j - k)\} \quad[k \le j][j - k \le as[i]]
\]

②卖出

\[f[i][j] = max\{f[i - W - 1][k] + bp[i] * (k - j)\} \quad[k \ge j][k - j \le bs[i]]
\]

③什么也不做

\[f[i][j] = max\{f[i][j],f[i - 1][j]\}
\]

其中③总共是\(O(n^2)\)的

①和②如果逐个枚举是\(O(n^3)\)的,无法承受

拆开式子可发现可以用单调队列优化成\(O(n^2)\)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define cls(s) memset(s,-0x3f3f3f3f,sizeof(s))
using namespace std;
const int maxn = 2005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int f[maxn][maxn],T,P,W,ap[maxn],bp[maxn],as[maxn],bs[maxn];
struct node{
int k,v;
}q[maxn];
int head,tail;
int main(){
T = read(); P = read(); W = read();
REP(i,T) ap[i] = read(),bp[i] = read(),as[i] = read(),bs[i] = read();
cls(f); f[0][0] = 0; int ans = 0;
for (int i = 1; i <= T; i++){
for (int j = 0; j <= P; j++) f[i][j] = f[i - 1][j];
if (i <= W){
for (int j = 0; j <= as[i]; j++)
f[i][j] = max(f[i][j],-ap[i] * j);
}
else {
head = 0; tail = -1;
for (int j = 0; j <= P; j++){
while (head <= tail && (j - q[head].k) > as[i]) head++;
while (head <= tail && q[tail].v < f[i - W - 1][j] + ap[i] * j) tail--;
q[++tail] = (node){j,f[i - W - 1][j] + ap[i] * j};
f[i][j] = max(f[i][j],q[head].v - ap[i] * j);
}
head = 0; tail = -1;
for (int j = P; j >= 0; j--){
while (head <= tail && (q[head].k - j) > bs[i]) head++;
while (head <= tail && q[tail].v < f[i - W - 1][j] + bp[i] * j) tail--;
q[++tail] = (node){j,f[i - W - 1][j] + bp[i] * j};
f[i][j] = max(f[i][j],q[head].v - bp[i] * j);
}
}
ans = max(ans,f[i][0]);
}
printf("%d\n",ans);
return 0;
}

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

  1. 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 ...

  2. 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 ...

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

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

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

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

  5. LUOGU P2569 [SCOI2010]股票交易(单调队列优化dp)

    传送门 解题思路 不难想一个\(O(n^3)\)的\(dp\),设\(f_{i,j}\)表示第\(i\)天,手上有\(j\)股的最大收益,因为这个\(dp\)具有单调性,所以\(f_i\)可以贪心的直 ...

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

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

  7. BZOJ 1855 股票交易 - 单调队列优化dp

    传送门 题目分析: \(f[i][j]\)表示第i天,手中拥有j份股票的最优利润. 如果不买也不卖,那么\[f[i][j] = f[i-1][j]\] 如果买入,那么\[f[i][j] = max\{ ...

  8. BZOJ1855 股票交易 单调队列优化 DP

    描述 某位蒟佬要买股票, 他神奇地能够预测接下来 T 天的 每天的股票购买价格 ap, 股票出售价格 bp, 以及某日购买股票的上限 as,  某日出售股票上限 bs, 并且每次股票交 ♂ 易 ( 购 ...

  9. BZOJ1855 [Scoi2010]股票交易[单调队列dp]

    题 题面有点复杂,不概括了. 后面的状态有前面的最优解获得大致方向是dp.先是瞎想了个$f[i][j]$表示第$i$天手里有$j$张股票时最大收入(当天无所谓买不买). 然后写了一个$O(n^4)$状 ...

  10. 股票交易——单调队列优化DP

    题目描述 思路 蒟蒻还是太弱了,,就想到半个方程就GG了,至于什么单调队列就更想不到了. $f[i][j]$表示第$i天有j$张股票的最大收益. 那么有四种选择: 不买股票:$f[i][j]=max( ...

随机推荐

  1. JavaScript: window.onload = function() {} 里面的函数不执行

    问题:写了一个最简单的页面.在script标签中使用的 window.onload = function() { function add() { //... } } 页面上:<div oncl ...

  2. mariadb源码编译安装及多实例

    准备文件源文件/app/mariadb-10.2.12.tar.gz cd /app/ tar xf mariadb-10.2.12.tar.gz cd  mariadb-10.2.12 mkdir ...

  3. Servlet学习笔记02——什么是http协议?

    1.http协议 (了解) (1)什么是http协议? 是一种网络应用层协议,规定了浏览器与web服务器之间 如何通信以及相应的数据包的结构. 注: a.tcp/ip: 网络层协议,可以保证数据可靠的 ...

  4. 怎么退出jQuery的each函数

    返回 'false' 将停止循环 (就像在普通的循环中使用 'break').返回 'true' 跳至下一个循环(就像在普通的循环中使用'continue'). 以下举例如何退出 each 函数和退出 ...

  5. Python类与对象--基础

    ## 类 - 具体事物的抽象和总结,是事物的共性,由属性和方法两个部分构成,比如一个Person类,有是身高.体重.肤色等属性,也有吃饭.睡觉.观察.等方法 ## 对象 - 具体的事物,单一.个体.特 ...

  6. json_encode 的小技巧

    做了一个 API 文档自动生成,解析的是每个 控制器类 的注释 json 数据,在做测试工具的时候,多层的 json 只有通过一个 textarea 把数据弄进去.如下图 怎么格式化 Json 数据并 ...

  7. 对Neural Machine Translation by Jointly Learning to Align and Translate论文的详解

    读论文 Neural Machine Translation by Jointly Learning to Align and Translate 这个论文是在NLP中第一个使用attention机制 ...

  8. [Link-Cut-Tree][BZOJ2002]弹飞绵羊

    题面 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上\(n\)个 ...

  9. 点击EditText可编辑,点击其他地方不可编辑

    我是在Fragment中实现的,在网上查了,有的说要回调Activity的onTouch事件,通过实验直接在Fragment中即可.如下: 我的EditText在ScrollView,因为Scroll ...

  10. J.U.C 系列之Atomic原子类

    一 什么是原子类? 所谓原子类必然是具有原子性的类,原子性操作--原子操作,百度百科中给的定义如下 "原子操作(atomic operation)是不需要synchronized" ...