题意:

有n+1个城市按顺序分布在同一直线上,现在需从0号城市按顺序走到n号城市(保证可达),从0号城市到i号城市需要消耗ai个糖果,每个城市都可以通过买/卖糖果来赚取更多的钱,价格分别是buyi和selli,保证selli<buyi。由于身上最多只能带C个糖果,且在起点0号城市时身上是没有钱的,问到达n号城市的最小花费(可以是负数,即亏损)?

思路:

(1)每次离开i城市时,将C补满,并记录身上每个糖果的购买价(因为钱是可以负的,所以一定可以补满)。

(2)每次到达i城市时,先用最便宜的糖果作为路上的固定消耗。

(3)卖出糖果挣钱,并以卖价继续持有它(比较难想到的点)。

(4)"退"掉不挣钱的糖果,注意是退不是卖,即按原价退掉,就当作从未买过这些糖果(这是每次都将C补满的原因)。

  问题在于怎么知道在哪个城市卖掉比较划算?

  因为selli<buyi,所以在同城市按sell卖出后再按buy买入来补满C是不划算的,会亏了中间的差价。我们得在后面的城市根据价格,来决策前面的城市该不该卖糖果。那么将可卖的糖果卖出后,以卖价s继续买入,会有两种情况:

  1、后面卖出可以赚更多。

    之前卖s价所带来利润已经到手,所以后面卖出有赚也是可以保证利润的。

  2、后面卖出会亏。

    按s价(这是当时新买入价)退掉这些糖果,就相当于在当时就卖掉了。

  1. #include <bits/stdc++.h>
  2. #define max(X,Y) ((X) > (Y) ? (X) : (Y))
  3. #define min(X,Y) ((X) < (Y) ? (X) : (Y))
  4. #define pii pair<int,int>
  5. #define INF 0x7f7f7f7f
  6. #define LL long long
  7. using namespace std;
  8. const int N=;
  9. int n;
  10. LL dis[N], buy[N], sell[N], cap;
  11. struct node
  12. {
  13. LL price;
  14. int cnt;
  15. node(){};
  16. node(LL p, int c):price(p),cnt(c){};
  17. };
  18.  
  19. LL cal()
  20. {
  21. deque<node> que(,node( buy[], cap) ); //当前持有。
  22. LL ans=cap*buy[]; //最小费用,补满。
  23.  
  24. for(int i=; i<=n; i++)
  25. {
  26. LL tmp=dis[i]-dis[i-]; //手续费
  27. LL sum=cap-tmp; //持有量。
  28.  
  29. for(; !que.empty(); que.pop_front()) //路上消耗最便宜的糖果。
  30. {
  31. node &t=que.front();
  32. if(t.cnt>tmp)
  33. {
  34. t.cnt-=tmp;
  35. break;
  36. }
  37. tmp-=que.front().cnt;
  38. }
  39.  
  40. //看能否卖掉一些。
  41. LL cnt=;
  42. for(; !que.empty(); que.pop_front())
  43. {
  44. node &t=que.front();
  45. if(t.price>sell[i]) break;
  46. cnt+=t.cnt;
  47. }
  48. if(cnt) que.push_front(node(sell[i], cnt)); //以sell价继续买入。
  49.  
  50. //看能否退掉一些:这里买比前面的还便宜,不如不带过来,那就按原价退
  51. for( ; !que.empty(); que.pop_back())
  52. {
  53. node &t=que.back();
  54. if(t.price<buy[i]) break;
  55. ans-=t.price*t.cnt;
  56. sum-=t.cnt; //当前持有量减少。
  57. }
  58.  
  59. que.push_back( node(buy[i], cap-sum) ); //补满!
  60. ans+= (cap-sum)*buy[i];
  61. }
  62. while(!que.empty()) //按原价退,相当于从未买过这些
  63. {
  64. node &t=que.front();que.pop_front();
  65. ans-=t.price*t.cnt;
  66. }
  67. return ans;
  68. }
  69.  
  70. int main()
  71. {
  72. freopen("input.txt", "r", stdin);
  73. int t;
  74. cin>>t;
  75. while(t--)
  76. {
  77. scanf("%d%d", &n, &cap);
  78. for(int i=; i<=n; i++) scanf("%lld", &dis[i]);
  79. for(int i=; i<=n; i++) scanf("%lld %lld", &buy[i], &sell[i]);
  80. printf("%lld\n",cal());
  81. }
  82. return ;
  83. }

HDU 5380 Travel with candy (贪心,单调队列)的更多相关文章

  1. hdu 5380 Travel with candy(双端队列)

    pid=5380">题目链接:hdu 5380 Travel with candy 保持油箱一直处于满的状态,维护一个队列,记录当前C的油量中分别能够以多少价格退货,以及能够推货的量. ...

  2. HDU 5380 Travel with candy 单调队列

    pid=5380">链接 题解链接:http://www.cygmasot.com/index.php/2015/08/16/hdu_5380 题意: n C 一条数轴上有n+1个加油 ...

  3. hdu 3706 Second My Problem First 单调队列

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3706 Second My Problem First Time Limit: 12000/4000 M ...

  4. HDU 6047 Maximum Sequence (贪心+单调队列)

    题意:给定一个序列,让你构造出一个序列,满足条件,且最大.条件是 选取一个ai <= max{a[b[j], j]-j} 析:贪心,贪心策略就是先尽量产生大的,所以就是对于B序列尽量从头开始,由 ...

  5. HDU 4122 Alice's mooncake shop 单调队列优化dp

    Alice's mooncake shop Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem ...

  6. hdu 4122 Alice's mooncake shop(单调队列)

    题目链接:hdu 4122 Alice's mooncake shop 题意: 有n个订单和可以在m小时内制作月饼 接下来是n个订单的信息:需要在mon月,d日,year年,h小时交付订单r个月饼 接 ...

  7. hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)

    题目链接:hdu 3415 Max Sum of Max-K-sub-sequence 题意: 给你一串形成环的数,让你找一段长度不大于k的子段使得和最大. 题解: 我们先把头和尾拼起来,令前i个数的 ...

  8. BZOJ 2424 订货(贪心+单调队列)

    怎么题解都是用费用流做的啊...用单调队列多优美啊. 题意:某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月初 ...

  9. HDU 4193 Non-negative Partial Sums【单调队列】

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4193 题意: 给定序列,可以把后面的连续的部分移到最前面来,问多少种移法使得最终得到的序列的前i项和 ...

随机推荐

  1. 基于HALCON的模板匹配方法总结 (转)

    很早就想总结一下前段时间学习HALCON的心得,但由于其他的事情总是抽不出时间.去年有过一段时间的集中学习,做了许多的练习和实验,并对基于HDevelop的形状匹配算法的参数优化进行了研究,写了一篇& ...

  2. UVA-10600(次小生成树)

    题意: 现在给一个图,问最小生成树和次小生成树的权值和是多少; 思路: 求最小生成树的两种方法,次小生成树是交换最小生成树的其中一条边得到的,现在得到了最小生成树,枚举不在次小生成树中的边,再求一边最 ...

  3. VC++读写文件

    目录 第1章读写文件    1 1.1 API    1 1.2 低级IO    1 1.2.1 文件序号    1 1.2.2 文本文件与二进制文件    1 1.3 流IO    2 1.4 Un ...

  4. 并不对劲的bzoj3994:loj2185:p3327[SDOI2015]约数个数和

    题目大意 设d(x)为x的约数个数,\(t\)组询问,给定\(n,m\)(\(t,m,n\leq5*10^4\)),求$ \sum^n_{i=1}\sum^m_{j=1}d(i*j)$ 题解 假设\( ...

  5. CodeForces-380C:Sereja and Brackets(线段树与括号序列)

    Sereja has a bracket sequence s1, s2, ..., sn, or, in other words, a string s of length n, consistin ...

  6. POJ1113:Wall (凸包:求最小的多边形,到所有点的距离大于大于L)

    Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the ...

  7. 查看JVM运行时堆内存

    利用jmap和MAT等工具查看JVM运行时堆内存 https://www.cnblogs.com/cjsblog/p/9561375.html jmap JDK自带了一些工具可以帮助我们查看JVM运行 ...

  8. 【HDU 1754】 I Hate It

    [题目链接] 点击打开链接 [算法] 树状数组的最值查询 详见这篇文章 : https://blog.csdn.net/u010598215/article/details/48206959 [代码] ...

  9. Top的VIRT是什么

    Top命令监控某个进程的资源占有情况  下面是各种内存: VIRT:virtual memory usage 1.进程“需要的”虚拟内存大小,包括进程使用的库.代码.数据等     2.假如进程申请1 ...

  10. 高可用性和PyMongo

        High Availability and PyMongo高可用性和PyMongo************************************ PyMongo makes it e ...