题目链接: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. 让Web API支持$format参数的方法

    public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web AP ...

  2. 【JDK】电脑上安装多个JDK ,修改JAVA_HOME后没有作用

    电脑上装了 C:\Program Files\Java\jdk1.6.0_43      C:\Program Files\Java\jdk1.7.0_80     C:\Program Files\ ...

  3. lr中定义字符串变量

    需要注意的是数组必须定义为固定的长度,如:char chary[20]: 5C2o"Go!\gm  nHH0 数组的最大长度为32064(32K),否则会出现“too many variab ...

  4. poj 1141 区间dp+递归打印路径

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30383   Accepted: 871 ...

  5. Angular JS 学习之简介

    1.Angular JS是一个JavaScript框架,它是一个以JavaScript编写的库,它可以通过<script>标签添加到HTML页面: <script src=" ...

  6. AngularJS 验证

    AngularJS ng-model 指令用于绑定输入元素到模型中. 模型对象有两个属性: user 和 email. 我们使用了 ng-show指令, color:red 在邮件是 $dirty 或 ...

  7. DAY7L2【C001】

    出自附中练习场[难度C]————————————————————————————————————————————————————————————— [试题描述]有 N 个任务, 每个任务最多只能完成一 ...

  8. C#解决从含身份证号码的Excel表格导入数据库的问题

    用C#做从Excel表导入SQL数据库时发现从EXCEL导入的身份证号码会变成科学表示方法. 解决这个问题是比较容易的,首先,打开电子表格,选中“身份证号码”一列,右键选择“设置单元格格式”,进入单元 ...

  9. ural 1342. Enterprise

    1342. Enterprise Time limit: 5.0 secondMemory limit: 64 MB To bind a broom it’s a hard work. As ther ...

  10. Educational Codeforces Round 15 [111110]

    注意一个词:连续 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<bits/ ...