题意:

有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价(这是当时新买入价)退掉这些糖果,就相当于在当时就卖掉了。

#include <bits/stdc++.h>
#define max(X,Y) ((X) > (Y) ? (X) : (Y))
#define min(X,Y) ((X) < (Y) ? (X) : (Y))
#define pii pair<int,int>
#define INF 0x7f7f7f7f
#define LL long long
using namespace std;
const int N=;
int n;
LL dis[N], buy[N], sell[N], cap;
struct node
{
LL price;
int cnt;
node(){};
node(LL p, int c):price(p),cnt(c){};
}; LL cal()
{
deque<node> que(,node( buy[], cap) ); //当前持有。
LL ans=cap*buy[]; //最小费用,补满。 for(int i=; i<=n; i++)
{
LL tmp=dis[i]-dis[i-]; //手续费
LL sum=cap-tmp; //持有量。 for(; !que.empty(); que.pop_front()) //路上消耗最便宜的糖果。
{
node &t=que.front();
if(t.cnt>tmp)
{
t.cnt-=tmp;
break;
}
tmp-=que.front().cnt;
} //看能否卖掉一些。
LL cnt=;
for(; !que.empty(); que.pop_front())
{
node &t=que.front();
if(t.price>sell[i]) break;
cnt+=t.cnt;
}
if(cnt) que.push_front(node(sell[i], cnt)); //以sell价继续买入。 //看能否退掉一些:这里买比前面的还便宜,不如不带过来,那就按原价退
for( ; !que.empty(); que.pop_back())
{
node &t=que.back();
if(t.price<buy[i]) break;
ans-=t.price*t.cnt;
sum-=t.cnt; //当前持有量减少。
} que.push_back( node(buy[i], cap-sum) ); //补满!
ans+= (cap-sum)*buy[i];
}
while(!que.empty()) //按原价退,相当于从未买过这些
{
node &t=que.front();que.pop_front();
ans-=t.price*t.cnt;
}
return ans;
} int main()
{
freopen("input.txt", "r", stdin);
int t;
cin>>t;
while(t--)
{
scanf("%d%d", &n, &cap);
for(int i=; i<=n; i++) scanf("%lld", &dis[i]);
for(int i=; i<=n; i++) scanf("%lld %lld", &buy[i], &sell[i]);
printf("%lld\n",cal());
}
return ;
}

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. 简易五子棋 V1.1.0

    main.cpp #include "fivechess.cpp" int main() { fivechess a; a.RunGame(); getchar(); return ...

  2. ios 图片拉伸方法

     前提:要注意图片的size和展示的图片view的size的大小. 假如图片高度50,展示图片view的高度30,拉伸会变成剪切. 如果图片尺寸不对,可以用mac自带的图片编辑器修改大小: 双击打开图 ...

  3. 频繁GC会造成卡顿

    频繁GC会造成卡顿 https://www.cnblogs.com/qcloud1001/p/9525078.html 一款app除了要有令人惊叹的功能和令人发指交互之外,在性能上也应该追求丝滑的要求 ...

  4. iOS NSInteger/NSUInteger与int/unsigned int、long/unsigned long之间的区别!

    在iOS开发中经常使用NSInteger和NSUInteger,而在其他的类似于C++的语言中,我们经常使用的是int.unsigned int.我们知道iOS也可以使用g++编译器,那么它们之间是否 ...

  5. servlet 3 文件上传

    1.up.jsp <%@ page language="java" pageEncoding="utf-8"%> <form action=& ...

  6. Windows下允许redis远程访问

    1.安装很简单,下载安装包安装即可,略过: 下载msi的安装包,会自动安装进服务: 2.远程访问 Redis默认只允许本地访问,要使Redis可以远程访问,需修改配置文件: 我用的redis3.2 , ...

  7. OkHttp解析

    今天花了一天时间研究了下OkHttp3的内部原理,记录在此处以便后期查阅 我们先来看下基本的使用方式: public void sendHttpRequest(String url,Callback ...

  8. P5072 [Ynoi2015]盼君勿忘

    传送门 一开始理解错题意了--还以为是两个子序列相同的话只算一次--结果是子序列里相同的元素只算一次-- 对于一个区间\([l,r]\),设其中\(x\)出现了\(k\)次,那么它的贡献就是它的权值乘 ...

  9. 51Nod 1179 最大的最大公约数(暴力大法好)

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; ; in ...

  10. iOS 加载Viewcontroller的几种方法

    // 一.根据StoryboardID(需要在Storyboard设置),通过ViewController所在的Storyboard来加载: UIStoryboard *storyboard = [U ...