【题解】[SCOI2010]股票交易
十分普通的DP+不平凡的转移
这道题状态十分明显。转移是\(O(n^4)\)的,过不去,我们需要优化。
一个十分显然的DP是\(f(i,j)\)表示第\(i\)天时候拥有\(j\)单位股票的最大收益。(可以小于零)。它的转移方式是:
\(f(i,j)=max(f(k,b)+(b-j) \times sell[t] or(buy[t]))\)
此时,我们发现一个转移需要两重循环,也就是\(O(n^2)\),加上右边的式子,就是\(O(n^4)\)的。
考虑优化:
对于转移方程,发现我们可以进行参变量分离。对状态转移方程进行代数变形。
- \(RHS=max(f(k,b)+b \times sell[t]-j \times sell[t])\)
- \(j\)在转移时,是最开始那个等式的\(LHS\),可以提前确定,从\(max\)拿出来。
- \(RHS=max(f(k,b)+b \times sell[t])-j\times sell[t]\)
- 于是,对于\(max(f(k,b)+b \times sell[t])\),可以拿数据结构维护了。
对于转移方法,我们只需要从\(f(i-W-1,j) , j\le maxP\)转移过来就好了。这一定是最优的那个状态,比它要早的状态一定会$\le f(i-W-1,j) $。
- 因为这个(晚的)状态在转移的时候,考虑过 从比他 (早的) 状态直接转移过来,于是\(f(i-W-1,j)\)不小于前面那个。
于是,我们可以将\(f(i-W-1,b) ,b\le maxP\)的所有状态压入某个数据结构。我们发现,对于这种数据结构的要求是:
- 维护最大值
- 可以清理过期状态(买入卖出股票有多少限制)
- 重置方便
就是单调队列吃饭的本领。
一句话解释单调队列:一个状态比你小(限制条件少)还比你强(数值大),那么你就被淘汰了。
单调队列是\(O(n)\)的,枚举\(LHS\)的\(i\)是\(O(n)\)的。总复杂度\(O(n^2)\),可以过了。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<bitset>
#include<vector>
#include<map>
#include<ctime>
#include<cstdlib>
#include<set>
#include<bitset>
#include<stack>
#include<list>
#include<cmath>
using namespace std;
#define RP(t,a,b) for(register ll (t)=(a),edd_=(b);t<=edd_;++t)
#define DRP(t,a,b) for(register ll (t)=(a),edd_=(b);t>=edd_;--t)
#define ERP(t,a) for(int t=head[a];t;t=e[t].to)
#define Min(a,b) ((a)<(b)?(a):(b))
#define TMP template<class ccf>
typedef long long ll;
TMP inline ccf qr(ccf k){
char c=getchar();
ccf x=0;
int q=1;
while(c<48||c>57)
q=c==45?-1:q,c=getchar();
while(c>=48&&c<=57)
x=x*10+c-48,c=getchar();
if(q==-1)
x=-x;
return x;
}
const int maxn=2e3+15;
inline void Swap(ll& a,ll& b){
ll k=a;
a=b;
b=k;
}
ll buy[maxn];
ll sell[maxn];
ll buytimes[maxn];
ll selltimes[maxn];
ll n,maxP,W;
ll dp[maxn][maxn];
int q[maxn];
TMP inline ccf Max(ccf a,ccf b){
if(a<b)
return b;
return a;
}
inline void init(){
memset(dp,-0xf,sizeof dp);
RP(t,1,n){
buy[t]=qr(1ll);
sell[t]=qr(1ll);
buytimes[t]=qr(1ll);
selltimes[t]=qr(1ll);
}
RP(t,1,n){
int head=1,tail=0;
if(t-W-1>0){
//trade
DRP(i,maxP,0){
while(head<=tail&&q[head]>i+selltimes[t])
head++;
while(head<=tail&&
dp[t-W-1][q[tail]]+1ll*q[tail]*sell[t]
<=dp[t-W-1][i]+1ll*i*sell[t]
)
--tail;
q[++tail]=i;
if(head<=tail)
dp[t][i]=max(dp[t][i],dp[t-W-1][q[head]]+(q[head]-i)*sell[t]*1ll);
}
//purchase
head=1,tail=0;
RP(i,0,maxP){
while(head<=tail&&q[head]<i-buytimes[t])
++head;
while(head<=tail&&
dp[t-W-1][q[tail]]+q[tail]*buy[t]
<=dp[t-W-1][i]+i*buy[t])
--tail;
q[++tail]=i;
if(head<=tail)
dp[t][i]=Max(dp[t][i],dp[t-W-1][q[head]]+(q[head]-i)*buy[t]*1ll);
}
}
//restart
RP(i,0,maxP){
dp[t][i]=Max(dp[t][i],dp[t-1][i]);
if(i<=buytimes[t])
dp[t][i]=Max(dp[t][i],-i*buy[t]);
}
}
ll ans=0;
RP(t,0,maxP)
ans=max(ans,dp[n][t]);
cout<<ans<<endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
while(~scanf("%lld%lld%lld",&n,&maxP,&W))
init();
return 0;
}
【题解】[SCOI2010]股票交易的更多相关文章
- 【BZOJ1855】[Scoi2010]股票交易 DP+单调队列
[BZOJ1855][Scoi2010]股票交易 Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预 ...
- [luogu] P2569 [SCOI2010]股票交易 (单调队列优化)
P2569 [SCOI2010]股票交易 题目描述 最近 \(\text{lxhgww}\) 又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,\(\te ...
- 单调队列优化DP || [SCOI2010]股票交易 || BZOJ 1855 || Luogu P2569
题面:P2569 [SCOI2010]股票交易 题解: F[i][j]表示前i天,目前手中有j股的最大收入Case 1:第i天是第一次购买股票F[i][j]=-j*AP[i]; (1<=j< ...
- 1855: [Scoi2010]股票交易[单调队列优化DP]
1855: [Scoi2010]股票交易 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1083 Solved: 519[Submit][Status] ...
- 洛谷P2569 [SCOI2010]股票交易
P2569 [SCOI2010]股票交易 题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股 ...
- BZOJ 1855: [Scoi2010]股票交易(DP+单调队列)
1855: [Scoi2010]股票交易 Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未 ...
- [SCOI2010]股票交易(单调队列优化dp)
[SCOI2010]股票交易 题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第 ...
- [bzoj1855][Scoi2010]股票交易_动态规划_单调队列
股票交易 bzoj-1855 Scoi-2010 题目大意:说不明白题意系列++...题目链接 注释:略. 想法:这个题还是挺难的. 动态规划没跑了 状态:dp[i][j]表示第i天手里有j个股票的最 ...
- bzoj1855: [Scoi2010]股票交易
Description 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价 ...
随机推荐
- luogu P3092 [USACO13NOV]没有找零No Change
题目描述 Farmer John is at the market to purchase supplies for his farm. He has in his pocket K coins (1 ...
- 某考试T1 game
题目背景 无 题目描述 Alice 和 Bob 在一个圆环上玩游戏.圆环上有 n 个位置,按照顺时针顺序 依次标号为 1 到 n.Alice 和 Bob 分别有一个数字集合,集合中都是在 [1, n− ...
- Eclipse的调试功能(转)(让Eclipse也能有VS的即时窗口那样的即时代码调试功能)
前言:可以很明确的说明,eclipse也有像vs那样的即时窗口来运行即时代码的功能. 调试的界面如下: 如果要像vs那样的即时调试功能,需要做一些设置,就是Expressions功能. 开通步骤:Wi ...
- python遍历当前目录并删除某文件
#coding: utf-8 """ this programe is to clear driverlog below this dir __author__:the_ ...
- 从头认识java-14.2 进一步了解数组
这一章节我们来全面了解一下数组. 1.数组在初始化之前.我们不能使用他的引用来做不论什么事情. package com.ray.ch14; public class Test { public sta ...
- CentOS SVN 服务器搭建
源码目录:/home/user/project 工程名:project 工程目录:/source/svn/project 访问地址:svn://ip/project 一. 安装svn yum inst ...
- pymongo的基本使用
#!/usr/bin/env python # -*- coding:utf-8 -*- """ MongoDB存储 在这里我们来看一下Python3下MongoDB的存 ...
- maximal-rectangle——找出最大矩形的面积
Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and ...
- swoole新手教程01-环境搭建及扩展安装
写在前面的废话 <swoole源代码分析>已经写了13章,整个swoole的核心架构基本都分析的差点儿相同了.于是心里一直以来想整理swoole的文档并写一份教程的想法就再度浮了出来. 实 ...
- Oracle 修改带数据的字段类型
http://www.cnblogs.com/LDaqiang/articles/1157998.html由于需求变动,现要将一个类型NUMBER(8,2)的字段类型改为 char.大体思路如下: ...