Hdu3401 Trade(dp 单调队列优化)最详细题解

累加器传送门:

http://blog.csdn.net/NOIAu/article/details/71775000

注:本题代码已经贴在ubuntu pastebin上

代码地址是 http://paste.ubuntu.com/24522455/

题目地址是http://acm.hdu.edu.cn/showproblem.php?pid=3401

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

中文翻译

最近,lxhgww沉迷于股票,经过几天的学习,他发现了一些常规模式。他可以预测未来的T天股市。 在第一天,你可以买价格APi或卖价格BPi的股票。
还有一些其他限制,在一天最多可以买到ASi股票,最多可以卖BSi股票。
两个交易日的间隔应超过W天。 也就是说,假设您在第二天交易(任何买入或卖出股票被视为交易),则下一个交易日必须在第(i + W + 1)天或之后。
而且,任何时候都不能拥有MaxP股票。
在第一天之前,lxhgww已经有无限的钱,但没有股票,当然他想从股票市场赚取尽可能多的钱。 所以问题来了,他能赚多少钱?

大概就是这么道题

这道题首先要构造dp状态转移方程,我们用dp[i][j]来表示第i天,我有j只股票,现在赚了多少钱,为什么这样定义呢,因为如果这样定义,然后转移的话,最后只需要for一遍就知道在最后一天最多盈利了多少

int maxn=-1;
for(int i=1;i<=maxp;i++){
    maxn=max(maxn,dp[T][i]);
}

那么数组定义出来了,怎么进行状态转移呢

我们发现,每次要计算一个dp[i][j]的时候,都要for从开头到i-W-1这么多天,在每一天,手持k张股票(i<=k <=maxp)而k又要分(k>=j)和(k< j)两种情况,因为要讨论是买入还是卖出,还要讨论是不是什么操作都不做,怎么办,好烦啊,代码复杂度也大,时间复杂度也完全不能承受啊啊啊,大概是O(T* T* maxp* maxp)

所以我们来想一下优化方案,因为题目的限制,交易(py)了一次之后,只能在W天之后才能进行交易(交易之后需要休息嘛)所以我们是否可以只讨论W天之前的状态呢,或许可以,但是题目又允许什么都不干啊,我说不定已经W+n天没有交易了(饥渴),那怎么办呢,我们这个时候再新加一个状态转移

dp[i][j]=max(dp[i][j],dp[i-1][j]);

也就是说,我在第i天和第i-1天的时候手持的股票是一样多了,也就是没有买,也没有卖,所以我的i-W-1天是从i-W-2天转移过来的,所以就不用考虑之前的有没有py了嘛,因为已经考虑过啦

那么既然我们只用考虑第i-W-1天的状态

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值