●BZOJ 1855 [Scoi2010]股票交易
题链:
http://www.lydsy.com/JudgeOnline/problem.php?id=1855
题解:
DP,单调队列优化。
(好久没做 DP题,居然还意外地想出来了)
定义 dp[i][k] 表示前 i天,手上还有 k股的最大收益。
(注意这个定义是个前缀的形式)
假设枚举到了第 i天,令 j=i-W-1。
那么dp[i][]就由dp[j][]转移而来。(说了是前缀形式的啦,就不要去枚举 j-1,j-2...了)
转移还是比较显然的:
枚举第 i 天结束手上还剩的股数 k:
枚举今日购买 d张:cmax(dp[i][k],dp[j][k-d]-d*AP);
枚举今日卖出 d张:cmax(dp[i][k],dp[j][k+d]+d*BP);
然后再来一个前缀的转移:cmax(dp[i][k],dp[i-1][k]);
这个复杂度是 T*MAXP*MAXP的,只能过 50分。
考虑优化(以购买转移为例),
显然转移的区间为连续的一段,
即若对于 dp[i][k]来说,转移来源是 dp[j][k-1]~dp[j][k-AS]。
且不难发现,如果 k-1>=x>y>=k-AS,且 dp[j][x] > dp[j][y]-val (val=(x-y)*AP),
那么如论如何dp[j][y]都不可能贡献答案。
所以就用单调队列维护每次转移的最值就好啦。
一个小技巧:在从 计算 dp[i][k] 到 计算 dp[i][k+1] 时,
显然单调队列里的旧元素的贡献相比刚刚加进队列的 newval=dp[j][k]来说都会减一个 AP,
但不好整体修改,(难道你想用数据结构维护?)
所以就令新加进队列的值 newval=dp[j][k]+k*AP,
保持好队列里的元素的相对大小关系就好了(即dp[j][k-1]始终比dp[j][k]多减了一个AP)。
(卖出的转移就类似了。)
最终复杂度可以做到 T*MAXP
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 2005
#define ll long long
#define filein(x) freopen(#x".in","r",stdin);
#define fileout(x) freopen(#x".out","w",stdout);
using namespace std;
ll dp[MAXN][MAXN],qv[MAXN],ANS,newval;
int T,MAXP,W,AP,BP,AS,BS,qk[MAXN];
void cmax(ll &a,ll b){
if(a<b) a=b;
}
int main()
{
filein(trade); fileout(trade);
memset(dp,0xcc,sizeof(dp)); dp[0][0]=0;
scanf("%d%d%d",&T,&MAXP,&W);
for(int i=1,j,l,r;i<=T;i++){ //2000
scanf("%d%d%d%d",&AP,&BP,&AS,&BS);
j=max(i-W-1,0);
for(int k=0;k<=MAXP;k++)//50->2000 //前缀形式,今日不做任何操作
cmax(dp[i][k],dp[i-1][k]);
l=1;r=1; qk[l]=0; qv[l]=dp[j][0];
for(int k=1;k<=MAXP;k++){//50->2000
//购置
//for(int d=1;d<=AS&&k-d>=0;d++) cmax(dp[i][k],dp[j][k-d]-1ll*d*AP);
while(l<=r&&k-qk[l]>AS) l++;
cmax(dp[i][k],dp[j][qk[l]]-1ll*(k-qk[l])*AP);
newval=dp[j][k]+1ll*k*AP;
while(l<=r&&qv[r]<=newval) r--;
r++; qk[r]=k; qv[r]=newval;
}
l=1;r=1; qk[l]=MAXP; qv[l]=dp[j][MAXP];
for(int k=MAXP-1;k>=0;k--){//50->2000
//出售
//for(int d=1;d<=BS&&k+d<=MAXP;d++) cmax(dp[i][k],dp[j][k+d]+1ll*d*BP);
while(l<=r&&qk[l]-k>BS) l++;
cmax(dp[i][k],dp[j][qk[l]]+1ll*(qk[l]-k)*BP);
newval=dp[j][k]-1ll*(MAXP-k)*BP;
while(l<=r&&qv[r]<=newval) r--;
r++; qk[r]=k; qv[r]=newval;
}
}
//for(int k=0;k<=MAXP;k++) cmax(ANS,dp[T][k]);
cout<<dp[T][0];
return 0;
}
●BZOJ 1855 [Scoi2010]股票交易的更多相关文章
- bzoj 1855: [Scoi2010]股票交易
Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价 ...
- BZOJ 1855 [Scoi2010]股票交易 ——动态规划
DP方程是比较简单的,主要有三种:什么都不做.买入.卖出. 发现买入卖出都是$\Theta (n^3)$但是转移方程都是线性的,而且决策和当前的情况是分开的. 所以可以单调队列优化. 复杂度$\The ...
- 1855: [Scoi2010]股票交易[单调队列优化DP]
1855: [Scoi2010]股票交易 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1083 Solved: 519[Submit][Status] ...
- BZOJ 1855: [Scoi2010]股票交易(DP+单调队列)
1855: [Scoi2010]股票交易 Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未 ...
- 单调队列优化DP || [SCOI2010]股票交易 || BZOJ 1855 || Luogu P2569
题面:P2569 [SCOI2010]股票交易 题解: F[i][j]表示前i天,目前手中有j股的最大收入Case 1:第i天是第一次购买股票F[i][j]=-j*AP[i]; (1<=j< ...
- [BZOJ 1855] 股票交易
Link: BZOJ 1855 传送门 Solution: 比较明显的$dp$模型 令$dp[i][j]$为第$i$天持有$j$支股票时的最大利润 对其购买股票和售出股票分别$dp$,这里以购买为例: ...
- 【BZOJ1855】[Scoi2010]股票交易 DP+单调队列
[BZOJ1855][Scoi2010]股票交易 Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预 ...
- 洛谷P2569 [SCOI2010]股票交易
P2569 [SCOI2010]股票交易 题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股 ...
- [luogu] P2569 [SCOI2010]股票交易 (单调队列优化)
P2569 [SCOI2010]股票交易 题目描述 最近 \(\text{lxhgww}\) 又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,\(\te ...
随机推荐
- python pip包管理
pip 是一个安装和管理 Python 包的工具 , 是 easy_install 的一个替换品.本文将详细说明 安装 pip 的方法和 使用 pip 的一些基本操作如安装.更新和卸载 python ...
- [知识梳理]课本3&9.1
函数:关键词:参数.返回值.函数返回类型.函数体. 函数按照返回类型,可以分为有参函数和无参函数. 函数根据是否有返回值,可以分为返回值函数和非返回值函数. 函数的定义:函数的定义可以放在任意 ...
- 构建自己的PHP框架--构建模版引擎(3)
之前我们实现了最简单的echo命令的模版替换,就是将{{ $name }}这样一段内容替换成<?php echo $name ?>. 现在我们来说下其他的命令,先来回顾下之前的定义 输出变 ...
- 分布式版本控制系统Git的安装及使用
Git的安装分为客户端安装和服务端安装,鉴于我平时码代码在windows环境下,因此本文客户端安装直接在windows环境,服务端安装在linux环境下(centos). Git客户端安装 客户端下载 ...
- JAVA 中的 反射
CLASS类 1) 在面向对象的世界里,万事万物皆对象. 在java中有两样东西不是面向对象 1.普通的数据类型(java中有封装类来弥补它) 2. java中静态的东西 2) 类是对象吗? 类是对象 ...
- 详解Ajax请求(二)——异步请求原理的分析
在上一文章里,我们分析了同步请求的原理.当浏览器向服务器发送同步请求时,服务处理同步请求的过程中,浏览器会处于等待的状态,服务器处理完请求把数据响应给浏览器并覆盖浏览器内存中原有的数据,浏览器重新加载 ...
- powerdesigner将name的名字赋给comment
1 PowerDesigner中批量根据对象的name生成comment的脚本 执行方法:Open PDM -- Tools -- Execute Commands -- Run Script Vb ...
- show engine innodb status输出说明
参考链接 (https://dev.mysql.com/doc/refman/5.7/en/innodb-standard-monitor.html) 其中有这样一句: For a descripti ...
- ActiveMQ学习系列(二)----生产者客户端(java)
上文主要简单地将activeMq搭建了起来,并且可以用web console去登录查看相关的后台功能. 本文将学习如何用java语言实现一个生产者客户端,主要参考了以下链接: http://activ ...
- (数字IC)低功耗设计入门(八)——物理级低功耗设计&to be continued?
前面学习了从系统级到门级的低功耗设计,现在简单地了解了一下物理级设计.由于物理级的低功耗设计与后端有关了,这里就不详细学习了.这里主要是学习了一些基本原则,在物理级,进行低功耗设计的基本原则是: ...