【单调队列优化DP】BZOJ1855-[Scoi2010]股票交易
【题目大意】
已知第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]股票交易的更多相关文章
- 【bzoj1855】 [Scoi2010]股票交易 单调队列优化DP
上一篇blog已经讲了单调队列与单调栈的用法,本篇将讲述如何借助单调队列优化dp. 我先丢一道题:bzoj1855 此题不难想出O(n^4)做法,我们用f[i][j]表示第i天手中持有j只股票时,所赚 ...
- 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 ...
- 2018.09.10 bzoj1855: [Scoi2010]股票交易(单调队列优化dp)
传送门 单调队列优化dp好题. 有一个很明显的状态设置是f[i][j]表示前i天完剩下了j分股票的最优值. 显然f[i][j]可以从f[i-w-1][k]转移过来. 方程很好推啊. 对于j<kj ...
- 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 ...
- 1855: [Scoi2010]股票交易[单调队列优化DP]
1855: [Scoi2010]股票交易 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1083 Solved: 519[Submit][Status] ...
- SCOI 股票交易 单调队列优化dp
这道题 我很蒙.....首先依照搞单调队列优化dp的一般思路 先写出状态转移方程 在想法子去优化 这个题目中说道w就是这一天要是进行操作就是从前w-1天转移而来因为之前的w天不允许有操作!就是与这些天 ...
- 动态规划专题(四)——单调队列优化DP
前言 单调队列优化\(DP\)应该还算是比较简单容易理解的吧,像它的升级版斜率优化\(DP\)就显得复杂了许多. 基本式子 单调队列优化\(DP\)的一般式子其实也非常简单: \[f_i=max_{j ...
- 「学习笔记」单调队列优化dp
目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
随机推荐
- MySQL备份之mysqlhotcopy与注意事项
此文章主要向大家介绍的是MySQL备份之mysqlhotcopy与其在实际操作中应注意事项的描述,我们大家都知道实现MySQL数据库备份的常用方法有三个,但是我们今天主要向大家介绍的是其中的一个比较好 ...
- 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 ...
- [bzoj 2844]线性基+高斯消元
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2844 又用到线性基+高斯消元的套路题了,因为经过高斯消元以后的线性基有非常好的序关系,所以 ...
- 怎么把centos虚拟机zip文件导入vm虚拟机中
执行以上三步就可以将一个压缩的centoszip文件导入到虚拟机中
- kettle基础操作
ETL:抽取(extract).转换(transform).加载(load)至目的端的过程: Kettle是ETL工具代表之一,是pentaho中的一个数据整合的一个组件.Kettle里包括多个Job ...
- [BZOJ2946] [Poi2000]公共串解题报告|后缀数组
给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 单词个数<=5,每个单词长度<=2000 尽管最近在学的是SAM...但是看到这个题还是忍不住想写SA... (其实是不 ...
- python面向对象——类和对象
一.三大编程范式 编程范式即编程的方法论,标识一种编程风格 三大编程范式: 1.面向过程编程(流水线式) 优点:极大的降低了程序的复杂度 缺点:应用场景固定住了,可扩展性差 2.函数式编程 特点: a ...
- git放弃本地commit,未push
如果不小心commit了一个不应该commit的修改,但是还没有push,想撤销那个commit. 步骤: a) git log:获取commit id: b) git reset --hard co ...
- 解析gtest框架运行机制
前言 Google test是一款开源的白盒单元测试框架,据说目前在Google内部已在几千个项目中应用了基于该框架的白盒测试. 最近的工作是在搞一个基于gtest框架搭建的自动化白盒测试项目,该项目 ...
- Android 曲线动画animation,类似加入购物车动画
按照惯例先放效果图:图中小球做抛物线运动 资源图片 1.首先布局文件activity_main.xml,布局很简单,就一个测试按钮 <RelativeLayout xmlns:android=& ...