Trade

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5864    Accepted Submission(s):
2022

Problem Description
Recently, lxhgww is addicted to stock, he finds some
regular patterns after a few days' study.
He forecasts the next T days' stock
market. On the i'th day, you can buy one stock with the price APi or sell one
stock to get BPi.
There are some other limits, one can buy at most ASi
stocks on the i'th day and at most sell BSi stocks.
Two trading days should
have a interval of more than W days. That is to say, suppose you traded (any buy
or sell stocks is regarded as a trade)on the i'th day, the next trading day must
be on the (i+W+1)th day or later.
What's more, one can own no more than MaxP
stocks at any time.

Before the first day, lxhgww already has infinitely
money but no stocks, of course he wants to earn as much money as possible from
the stock market. So the question comes, how much at most can he earn?

 
Input
The first line is an integer t, the case number.
The
first line of each case are three integers T , MaxP , W .
(0 <= W < T
<= 2000, 1 <= MaxP <= 2000) .
The next T lines each has four
integers APi,BPi,ASi,BSi( 1<=BPi<=APi<=1000,1<=ASi,BSi<=MaxP),
which are mentioned above.
 
Output
The most money lxhgww can earn.
 
Sample Input
1
5 2 0
2 1 1 1
2 1 1 1
3 2 1 1
4 3 1 1
5 4 1 1
 
Sample Output
3
 
Author
lxhgww
 
Source
 
Recommend
lcy

Solution

题目大意是股票在$t$天内每天买或卖或不作为,知道每一天每一支股票的买卖价格$api,bpi$和限购或卖的量$asi,bsi$,以及每天最多持有的股票数$maxp$,还有每次交易必须隔至少$w$的限制,求最大的收益。

DP式定义为$dp[i][j]$表示在第$i$天持有$j$张股票的最大收益。

转移有三方面:

1、不作为:$dp[i][j]=dp[i-1][j]$(所以转移2、3时不用考虑$i-w-1$天前)

2、买进:$dp[i][j]=dp[i-w-1][k]-(j-k)*api=>max(dp[i-w-1][k]+k*api)-j*api$

3、卖出:$dp[i][j]=dp[i-w-1][k]+(k-j)*bpi=>max(dp[i-w-1][k]+k*bpi)-j*bpi$

观察2、3,发现max部分就是单调队列的结构,所以每次对于j找最优决策点(并且满足每天的各种限制),将$n^3$压成了$n^2$。

Code

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std; int t, maxp, w;
int dp[][], ap[], as[], bp[], bs[]; struct Node {
int num, m;
} q[]; int main() {
int T;
scanf("%d", &T);
while(T --) {
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]);
for(int i = ; i <= t; i ++)
for(int j = ; j <= maxp; j ++) dp[i][j] = -inf;
for(int i = ; i <= w + ; i ++)
for(int j = ; j <= min(maxp, as[i]); j ++)
dp[i][j] = -j * ap[i];
dp[][] = ;
for(int i = ; i <= t; i ++) {
for(int j = ; j <= maxp; j ++) {
dp[i][j] = max(dp[i][j], dp[i - ][j]);
}
if(i - w - <= ) continue;
int pre = i - w - ;
int h = , t = ;
for(int j = ; j <= maxp; j ++) {
int f = dp[pre][j] + ap[i] * j;
while(h <= t && q[t].m <= f) t --;
q[++ t].num = j;
q[t].m = f;
while(h <= t && q[h].num + as[i] < j) h ++;
dp[i][j] = max(dp[i][j], q[h].m - ap[i] * j);
}
h = ; t = ;
for(int j = maxp; j >= ; j --) {
int f = dp[pre][j] + bp[i] * j;
while(h <= t && q[t].m <= f) t --;
q[++ t].num = j;
q[t].m = f;
while(h <= t && q[h].num - bs[i] > j) h ++;
dp[i][j] = max(dp[i][j], q[h].m - bp[i] * j);
}
}
int res = -inf;
for(int i = ; i <= maxp; i ++) res = max(res, dp[t][i]);
printf("%d\n", res);
}
return ;
}

【HDU】3401:Trade【单调队列优化DP】的更多相关文章

  1. HDU 3401 Trade(单调队列优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 题意:炒股.第i天买入一股的价钱api,卖出一股的价钱bpi,最多买入asi股,最多卖出bsi股 ...

  2. HDU 3401 Trade(斜率优化dp)

    http://acm.hdu.edu.cn/showproblem.php?pid=3401 题意:有一个股市,现在有T天让你炒股,在第i天,买进股票的价格为APi,卖出股票的价格为BPi,同时最多买 ...

  3. HDU-3401 Trade 单调队列优化DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 DP方程容易想出来,f[i][j]表示第i天拥有j个股票的最优解,则: 1.不买不卖,f[i][ ...

  4. hdu3401 Trade 单调队列优化dp

    Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  5. 【单调队列优化dp】HDU 3401 Trade

    http://acm.hdu.edu.cn/showproblem.php?pid=3401 [题意] 知道之后n天的股票买卖价格(api,bpi),以及每天股票买卖数量上限(asi,bsi),问他最 ...

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

  7. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  8. 单调队列优化DP——习题收集

    前言 感觉可以用单调队列优化dp的模型还是挺活的,开个随笔记录一些遇到的比较有代表性的模型,断续更新.主要做一个收集整理总结工作. 记录 0x01 POJ - 1821 Fence,比较适合入门的题, ...

  9. Parade(单调队列优化dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others)    ...

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

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

随机推荐

  1. vi 编辑器使用技巧

    1.由命令"vi --version"所显示的内容知vi的全局配置文件 2.显示行号   ,非编辑模式输入 : set nu 3.显示颜色 1)在文件中找到 "synta ...

  2. Linux内存初始化【转】

    转自:http://www.cnblogs.com/super-king/p/3291120.html start_kernel -> setup_arch 在这个函数中我们主要看这几个函数. ...

  3. .net 下的集合

    集合的操作在编码的时候很常见.但是由于经常使用几种集合.而忽略了一些不常用的集合.在这里我整理下. 首先先了解下接口: 1.IEnumerable,返回一个循环访问集合的枚举器. 2.IEnumera ...

  4. Github授权新的设备ssh接入

    为Mac生成公钥 步骤: 检查本机是否已有公钥 ls -la ~/.ssh 将原来的公钥删除 rm -rf ~/.ssh 生成新的公钥(填自己的邮箱),然后除了密码,一路默认 ssh-keygen - ...

  5. c语言格式控制符

    http://zhidao.baidu.com/link?url=-YJjz3U0fd_eSW9eLa8ankGo_QbyOOOaKYWyAY9g4mKWQj0DN6l12OSLJz24U8jCwo1 ...

  6. python网络编程-paramiko

    python基础学习日志day8-paramiko 一:简介 Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 现有这样的需求:需要使用windows客户端,远程连 ...

  7. Nginx - 压缩模块

    1. 前言 在 Nginx 中与网页压缩相关的模块有两个:一个是 HttpGzipModule,另一个是 HttpGzipStaticModule.前者用于启用在文件传输过程中使用 gzip 压缩,而 ...

  8. 虚拟机 ubuntu 16.04

    下载地址:https://www.ubuntu.com/download/desktop 使用虚拟机直接安装

  9. python之assert断言

    assert只是一个检查,为真不做任何事,不为真时,抛出异常,并包含错误信息 1.根据布尔值判断 2.判断是否相等 3.返回值是否为空 4.是否包含某值 x in y 其他方法,可以参考http:// ...

  10. BFS && DFS

    HDOJ 1312 Red and Black http://acm.hdu.edu.cn/showproblem.php?pid=1312 很裸的dfs,在dfs里面写上ans++,能到几个点就调了 ...