Trade

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Appoint description: 

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.  
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
 
题意:
总共有T天,任何时刻最多只能有MaxP股票,如果第i天买股票,那么必须在第i + W + 1天或之后 在买,卖也是如此。
第i天能够买AS[i]的股票,能够卖BS[i]的股票,买的价格为AP[i],卖的价格为BP[i],开始的时候没有任何股票,但是有足够的
钱。问能最多赚多少钱。
思路:
dp[i][j]表示第i天有j个股票能赚多少钱。
那么可以分三种情况:
1)什么都不做 dp[i][j] = max(dp[i][j],dp[i-1][j]);
2)买了股票 dp[i][j] = max(dp[i][j],dp[i-W-1][k] - (j - k) * AP[i]);
3)卖了股票 dp[i][j] = max(dp[i][j],dp[i-W-1][k] + (k - j) * BP[i]); 
 
按照朴素的做法枚举天数,股票数j,k复杂度为O(n ^ 3);
将买股票的状态方程转化一下成 dp[i][j] = max(dp[i-W-1][k] + k * AP[i]) - j * AP[i];令f[i-W-1] = dp[i-W-1][k] + k * AP[i],
那么dp[i][j] = max(f[i-W-1]) - j * AP[i];对于f[i-W-1]可以用单调队列来求。这样复杂度就成了n ^ 2。买股票的也类似。
 
  1. /*
  2. * Author: sweat123
  3. * Created Time: 2016/7/12 13:52:38
  4. * File Name: main.cpp
  5. */
  6. #include<set>
  7. #include<map>
  8. #include<queue>
  9. #include<stack>
  10. #include<cmath>
  11. #include<string>
  12. #include<vector>
  13. #include<cstdio>
  14. #include<time.h>
  15. #include<cstring>
  16. #include<iostream>
  17. #include<algorithm>
  18. #define INF 1<<30
  19. #define MOD 1000000007
  20. #define ll long long
  21. #define lson l,m,rt<<1
  22. #define key_value ch[ch[root][1]][0]
  23. #define rson m+1,r,rt<<1|1
  24. #define pi acos(-1.0)
  25. using namespace std;
  26. const int MAXN = ;
  27. struct node{
  28. int num;
  29. int val;
  30. node(int tnum = ,int tval = ):num(tnum),val(tval){}
  31. };
  32. deque<node>q;
  33. int dp[MAXN][MAXN],T,MaxP,W;
  34. int AP[MAXN],BP[MAXN],AS[MAXN],BS[MAXN];
  35. int main(){
  36. int t;
  37. scanf("%d",&t);
  38. while(t--){
  39. scanf("%d%d%d",&T,&MaxP,&W);
  40. for(int i = ; i <= T; i++){
  41. scanf("%d%d%d%d",&AP[i],&BP[i],&AS[i],&BS[i]);
  42. }
  43. for(int i = ; i <= T; i++){
  44. for(int j = ; j <= MaxP; j++){
  45. dp[i][j] = -INF;
  46. }
  47. }
  48. for(int i = ; i <= W+; i++){//第一天到W+1天只都是只能买的
  49. for(int j = ; j <= min(MaxP,AS[i]); j++){
  50. dp[i][j] = - AP[i] * j;
  51. }
  52. }
  53. dp[][] = ;
  54. for(int i = ; i <= T; i++){
  55. for(int j = ; j <= MaxP; j++){//什么都不做
  56. dp[i][j] = max(dp[i-][j],dp[i][j]);
  57. }
  58. if(i <= W + )continue;//已经预处理了
  59. q.clear();
  60. int bf = i - W - ;//队列中保存i - W - 1天的信息
  61. for(int j = ; j <= MaxP; j++){//有多少股票
  62. int nowf = dp[bf][j] + j * AP[i];//队列维护这个最大值
  63. while(!q.empty() && q.back().val < nowf){
  64. q.pop_back();
  65. }
  66. q.push_back(node(j,nowf));
  67. while(!q.empty() && j - q.front().num > AS[i]){//队列里面存的都是i - W - 1天的信息 对于第i天
  68. //如果第i天的股票数 - (i - W - 1)天的股票数大于今天能买的数,那就不符合
  69. q.pop_front();
  70. }
  71. dp[i][j] = max(dp[i][j],q.front().val - j * AP[i]);
  72. }
  73. q.clear();
  74. for(int j = MaxP; j >= ; j--){
  75. int nowf = dp[bf][j] + j * BP[i];
  76. while(!q.empty() && q.back().val < nowf){
  77. q.pop_back();
  78. }
  79. q.push_back(node(j,nowf));
  80. while(!q.empty() && q.front().num - j > BS[i]){
  81. q.pop_front();
  82. }
  83. dp[i][j] = max(dp[i][j],q.front().val - j * BP[i]);
  84. }
  85. }
  86. int ans = ;
  87. for(int i = ; i <= MaxP; i++){
  88. ans = max(ans,dp[T][i]);
  89. }
  90. printf("%d\n",ans);
  91. }
  92. return ;
  93. }

hdu 3401 单调队列优化DP的更多相关文章

  1. hdu 3401 单调队列优化+dp

    http://acm.hdu.edu.cn/showproblem.php?pid=3401 Trade Time Limit: 2000/1000 MS (Java/Others)    Memor ...

  2. hdu 3401 单调队列优化动态规划

    思路: 动态方程很容易想到dp[i][j]=max(dp[i][j],dp[i-w-1][j-k]-k*ap[i],dp[i-w-1][j+k]+k*bp[i]): dp[i][j]表示第i天拥有j个 ...

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

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

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

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

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

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

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

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

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

  8. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

  9. hdu3401:单调队列优化dp

    第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...

随机推荐

  1. Linux0.11内核--加载可执行二进制文件之1.copy_strings

    从现在开始就是分析最后的核心模块exec.c了,分析完这个文件后,就会和之前的所有分析形成一个环路,从创建进程.加载进程程序到进程调度.内存管理. exec.c的核心do_execve函数很长,而且用 ...

  2. nodejs的child_process同步异步

    nodejs是一种单线程模型,但是,使用nodejs的child_process模块可以实现多进程任务.利用child_process可以创建子进程,实现子进程和主进程之间的通信. nodejs v0 ...

  3. Android measure过程分析

    作为一名Android开发人员,我们都知道一个View从无到有,会经历3个阶段: 1. measure/测量阶段,也就是确定某个view大小的过程: 2. layout/布局阶段,也就是确定其左上右下 ...

  4. iOS开发之功能模块--长方形UIImage截取中间最大正方形区域

    这里直接用CoreGraphics的一些处理图片的方法,本身不难,但是有些时候用的不多,就会遗忘掉使用方法的细节.下面就直接展示关键源码,以便下次重复需求,就可以立马找回. 该方法中在UIImage的 ...

  5. mac osx install mysql

    (1) download mysql dmg (2) install (3) /usr/local/mysql/bin/mysql -u root -p change password

  6. 解析UML箭头、线条代表的意义(转)

    在学习UML过程中,你经常会遇到UML类图关系,这里就向大家介绍一下UML箭头.线条代表的意义,相信通过本文的介绍你对UML中箭头.线条的意义有更明确的认识. AD: 本节向大家学习一下UML箭头.线 ...

  7. MVC3.0----整理之一

    1.ViewBag对象是动态解析对象 @{ ViewBag.Title = "Insert"; } 不仅可以把单个的对象绑定到 ViewBag上,还可以直接绑定List ViewB ...

  8. Cannot execute as the database principal because the principal "guest" does not exist, this type of principal cannot be impersonated, or you do not have permission.

    今天遇到这样一个问题:一个系统的作业需要给系统Support人员开放SQL Agent下作业的查看.执行权限.数据库版本为SQL Server 2014 SP2,给这个系统Support人员的NT账号 ...

  9. 【转载】Linux中常用操作命令

    说明:开始学习linux系统,为了方便查看,特转载一篇Linux中常用操作命令,转载地址:http://www.cnblogs.com/laov/p/3541414.html 正文: Linux简介及 ...

  10. monkeyrunner 自动化测试 图片对比的实现

    这个功能在网上看了好多人的代码,但是总是在image.writeToFile('D:/tmp/images/black.png','png')这一句出错.查了google的API也感觉没错呀. 后来自 ...