题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401

题目大意:现在要你去炒股,给你每天的开盘价值,每股买入价值为ap,卖出价值为bp,每天最多买as股,最多卖出bs股,并且要求两次买卖必须间隔W天,问你在T天内如何进行炒股操作从而获得最大收益。

解题思路:先吐槽一下,会单调队列但不会dp不行,会dp但不会单调队列也不行!!开始dp动态转移方程倒是写对了,然后算算时间复杂度T*T*Maxp*Maxp,优化不得当,一直以为是dp思路错了,囧。

对于有单调队列参与dp的题,dp方程必须准确先写好,然后再观察可否用单调队列。

dp[i][j]:表示第i天手上持有j股的最大利益。三种决策:

{ -------1、不买不卖  dp[i-1][j]

dp[i][j]=max { -------2、买   dp[r][k]-ap[i]*(j-k)  (j>=k,r<=i-w-1)

{ -------3、卖  dp[r][k]+bp[i]*(k-j)  (j<=k,r<=i-w-1)

由dp方程可知时间复杂度为T*T*Maxp*Maxp,其实仔细观察可以看出,r其实就等于i-w-1(联系决策1想想为什么),时间复杂度降低一维。

看第二个dp转移方程,dp[i][j]=max(dp[i][j],dp[i-w-1][k]-ap[i]*(j-k)).

dp[i-w-1][k]-ap[i]*(j-k)=(dp[i-w-1][k]+ap[i]*k)-ap[i]*j , 在j固定的情况下(dp[i][j]固定),k变式子值变,我们只需保存变化过程中的最大值即可,很容易想到单调队列。决策三亦是如此。因为要保存最大值,所以买是j从0开始和卖是j从Maxp开始,最大值优先。

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std; const int maxn=;
const int oo=0x3fffffff;
int ap[maxn], bp[maxn], as[maxn], bs[maxn];
int dp[maxn][maxn];
int W, T, Maxp, n; struct node
{
int num, val;
}que[maxn]; int main()
{
cin >> T;
while(T--)
{
cin >> n >> Maxp >> W;
for(int i=; i<=n; i++)
for(int j=; j<=Maxp; j++) dp[i][j]=-oo;
for(int i=; i<=n; i++) scanf("%d%d%d%d",ap+i,bp+i,as+i,bs+i);
for(int i=; i<=n; i++) dp[i][]=;
for(int i=; i<=W+; i++)
for(int j=; j<=as[i]; j++) dp[i][j]=-j*ap[i];
for(int j=; j<=Maxp; j++)
for(int i=; i<=W+; i++)
dp[i][j]=max(dp[i][j],dp[i-][j]);
for(int i=W+; i<=n; i++)
{
int front=, tail=-;
for(int j=; j<=Maxp; j++)
{
dp[i][j]=max(dp[i][j],dp[i-][j]);
while(front<=tail&&que[tail].val<=dp[i-W-][j]+ap[i]*j) tail--;
que[++tail].val=dp[i-W-][j]+ap[i]*j, que[tail].num=j;
while(front<=tail&&j-que[front].num>as[i]) front++;
dp[i][j]=max(dp[i][j],que[front].val-ap[i]*j);
}
front=, tail=-;
for(int j=Maxp; j>=; j--)
{
while(front<=tail&&que[tail].val<=dp[i-W-][j]+bp[i]*j) tail--;
que[++tail].val=dp[i-W-][j]+bp[i]*j, que[tail].num=j;
while(front<=tail&&que[front].num-j>bs[i]) front++;
dp[i][j]=max(dp[i][j],que[front].val-bp[i]*j);
}
}
int maxx=;
for(int i=; i<=Maxp; i++)
maxx=max(maxx,dp[n][i]);
printf("%d\n",maxx);
}
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. this和super

    1.this * 每个类的每个非静态方法(没有被static修饰)都会隐含一个this引用名称,它指向调用这个方法的对象. * 当在方法中使用本类的属性时,都会隐含地使用this名称,当然也可以明确指 ...

  2. JavaScript中设置元素class的三种方法小结

    第一.element.setAttribute('class','abc');  第二.element.setAttribute('className', 'abc') : 第三.element.cl ...

  3. DSP using MATLAB 示例 Example3.10

    用到的性质 上代码: n = -5:10; x = rand(1,length(n)) + j * rand(1,length(n)); k = -100:100; w = (pi/100)*k; % ...

  4. Codeforces 335C Sorting Railway Cars

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  5. Nico Nico Ni~(完全背包)

    Time Limit:2000MS  Memory Limit:65535K Type: Program   Language: Not Limited Description Lys plays L ...

  6. jQuery实现等比例缩放大图片

      在布局页面时,有时会遇到大图片将页面容器“撑破”的情况,尤其是加载外链图片(通常是通过采集的外站的图片).那么本文将为您讲述使用jQuery如何按比例缩放大图片,让大图片自适应页面布局. 通常我们 ...

  7. js中for in 和 for each in的用法和区别

    区别一:           for in是javascript 1.0 中发布的.         for each in是作为E4X标准的一部分在javascript 1.6中发布的,而它不是EC ...

  8. python 代码片段22

    #coding=utf-8 class AddressBookEntry(object): version=0.1 def __init__(self, name,phone): self.name ...

  9. ssh myeclipse的bug

    1 有时候复制完一个类的时候,myeclispe会少复制一些方法.很坑爹.复制的时候最好从新创建让后粘贴 2 有时候jsp页面经过修改该以后,在网页上显示的还是原来的页面,很坑爹.删掉tomcat然后 ...

  10. BZOJ3659 : Which Dreamed It

    首先判断一下是否无解,并剔除孤立点. 根据best theorem,有向图中以$i$为起点的欧拉回路个数为: 以$i$为根的树形图个数$\times\prod_{i=1}^n (deg(i)-1)!$ ...