【HDU】3401:Trade【单调队列优化DP】
Trade
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5864 Accepted Submission(s):
2022
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?
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.
5 2 0
2 1 1 1
2 1 1 1
3 2 1 1
4 3 1 1
5 4 1 1
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】的更多相关文章
- HDU 3401 Trade(单调队列优化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 题意:炒股.第i天买入一股的价钱api,卖出一股的价钱bpi,最多买入asi股,最多卖出bsi股 ...
- HDU 3401 Trade(斜率优化dp)
http://acm.hdu.edu.cn/showproblem.php?pid=3401 题意:有一个股市,现在有T天让你炒股,在第i天,买进股票的价格为APi,卖出股票的价格为BPi,同时最多买 ...
- HDU-3401 Trade 单调队列优化DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 DP方程容易想出来,f[i][j]表示第i天拥有j个股票的最优解,则: 1.不买不卖,f[i][ ...
- hdu3401 Trade 单调队列优化dp
Trade Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- 【单调队列优化dp】HDU 3401 Trade
http://acm.hdu.edu.cn/showproblem.php?pid=3401 [题意] 知道之后n天的股票买卖价格(api,bpi),以及每天股票买卖数量上限(asi,bsi),问他最 ...
- 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 ...
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
- 单调队列优化DP——习题收集
前言 感觉可以用单调队列优化dp的模型还是挺活的,开个随笔记录一些遇到的比较有代表性的模型,断续更新.主要做一个收集整理总结工作. 记录 0x01 POJ - 1821 Fence,比较适合入门的题, ...
- Parade(单调队列优化dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others) ...
- 1855: [Scoi2010]股票交易[单调队列优化DP]
1855: [Scoi2010]股票交易 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1083 Solved: 519[Submit][Status] ...
随机推荐
- 5 - django-csrf-session&cookie
目录 1 CSRF跨站请求伪造 1.1 CSRF攻击介绍及防御 1.2 防御CSRF攻击 1.2.1 验证 HTTP Referer 字段 1.2.2 在请求地址中添加 token 并验证 1.2.3 ...
- Shell-修改MySQL默认root密码
Code: mysqltmppwd=`cat /tmp/.mysql_secret | cut -b 87-102` mysqladmin -u root -p${mysqltmppwd} passw ...
- spring学习之三 数据库操作jdbcTemplate
概念 jdbcTemplate就Spring对数据库持久化技术的实现,通过它可以对数据库进行CRUD等操作. JDBCTemplate和代码实现 public void jdbcadd() { Dri ...
- Mysql Limit操作
oracle : || mysql: contact contact_ws 拼接 Font Size: Large | Medium | Small select * from tabl ...
- INSTEAD OF与AFTER触发器
INSTEAD OF 触发器 AFTER 触发器(也叫“FOR”触发器)会在触发 insert.update 或是delect 动作之后执行.例如,一个 Employees 表上的 AFTER 触发器 ...
- python 统计MySQL大于100万的表
一.需求分析 线上的MySQL服务器,最近有很多慢查询.需要统计出行数大于100万的表,进行统一优化. 需要筛选出符合条件的表,统计到excel中,格式如下: 库名 表名 行数 db1 users 1 ...
- java对象与xml相互转换工具类
public class XmlHelper { /** * Object转XML * * @param object * @return * @throws Exception */ public ...
- 大数据统计分析平台之三、Kibana安装和使用
kibana安装 1.到官网下载kibana: cd /usr/local/software wget https://artifacts.elastic.co/downloads/kibana/ki ...
- 【LOJ】#2039. 「SHOI2015」激光发生器
题解 我永远都写不对计算几何-- 首先找到反射的线段比较好找,扫一遍所有线段然后找交点在镜子上并且交点离起点最近的那条线段 然后旋转的时候,有可能是顺时针,也有可能是逆时针,要找出法线,然后判断法线和 ...
- 【LOJ】#2432. 「POI2014」代理商 Couriers
题解 建出一个主席树,因为出现大于区间一半的数只能有一个,就看看左右区间的增加有没有大于一半,如果有就走向那个子树,如果没有那么返回0 代码 #include <iostream> #in ...