省钱加油(Fuel Economy)题解
题目##
农夫约翰决定去做一个环游国家旅行,为了不让他的奶牛们感到孤单,于是他决定租一辆货车带领他的奶牛们一起去旅行。这辆货车的油箱最多可以承载G 个单位的油,同时为了简化问题,规定每一个单位的油可以行使一个单位的距离。约翰从起点出发到终点总共要经过D 个单位的距离。约翰知道自己很有可能要在中途的过程中加几次油。他将中途的N 个加油站(加油站看成是排成一条直线的)的位置都记录下来了。对于每一个加油站,他记录了这个加油站到起点的距离Xi,同时也记录了这个加油站的每个单位的油价Yi。
问题描述:
给定以上这些信息,约翰开始的时候有B 个单位的油,请帮助计算约翰为了
到达终点至少要在中途花费多少钱加油。如果约翰不能到达终点,那么就输出-1。
注意这题的结果可能超过longint 的范围。
输入格式:
第一个四个整数,N,G,B,D。
接下来N 行,每行两个整数,分别表示每个加油站的Xi 和Yi。
输出格式:
输出为了到达终点最少需要花费的钱的数量,如果不能到达就输出-1。
输入输出样例:
fuel.in
4 10 3 17
2 40
9 15
5 7
10 12
fuel.out
174
数据范围:
1<=G<=1000000,1<=D<=1000000000,1<=N<=50000,0<=Xi<=D,1<=Yi<=1000000,0<=B<=D。
样例说明:样例中,约翰先是行使了2 个单位的距离,然后在位置为2 的加油站购买了2 个单位的油,花费2*40=80,然后在位置为5 的加油站加满了油,花费7*10=70,然后他到达位置为10 的加油站,加了两个单位的油,花费为12*2,于是他总的花费是80+70+24=174。
引例##
看到这道题目,首先想到的是DP,但是1<=N<=50000,1<=D<=1000000000
可以很容易地让我们放弃这个想法(光是内存方面就明显不允许)。然而,看到油价、路程等,我就联想到了之前做过的题目:Duff and Meat(CodeForces 588A)
。这道题目大意是这样子的:Duff要在N天内购买食材,第i天的食物需求与单位食物价格分别是x[i]
与p[i]
,第i天不仅可以购买当天的食物,也可以把后面任意几天的食物都买下。当时看到这题我也是手足无措,是看到tips里的greedy(贪心)
才想到了一个算法:在第i天时,只要后面的连续几天的食物价格大于当天食物价格,就在这一天都预先买下。这题的核心思路大致相仿。
题解##
根据上面的引例中的算法,我们可以写出一个朴素的算法,即先对数组x
升序排序,这会使后面的算法操作方便许多。然后在按照上面的步骤进行贪心。对每一站进行遍历,找出后面比它更便宜的一站,时间复杂度为O(n^2)
。在极限数据N=50000
下很有可能超时。这时候就需要用到一点技巧,在贪心前花费O(N)的时间利用栈的特性进行预处理,这样,整个程序的时间复杂度就可以降低到O(N)
,秒杀N=50000
的情况。
参考程序##
var
ns,s,x,y:array[0..50001] of int64;
ans,sl,gasn,st,n,g,b,d,j,p:int64;
i:longint;
function min(a,b:int64):int64;
begin
if a>b then exit(b);
exit(a);
end;
procedure sort(l,r:longint);
var
i,j,x1,y1:int64;
begin
i:=l;j:=r;
x1:=x[(l+r) div 2];
repeat
while x[i]<x1 do inc(i);
while x1<x[j] do dec(j);
if not(i>j) then begin
y1:=x[i];x[i]:=x[j];x[j]:=y1;
y1:=y[i];y[i]:=y[j];y[j]:=y1;
inc(i);dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;
begin
assign(input,'fuel.in');assign(output,'fuel.out');
reset(input);rewrite(output);
readln(n,g,b,d);
for i:=1 to n do readln(x[i],y[i]);
sort(1,n);sl:=0;
for i:=n downto 1 do begin
while (sl>=1) and (y[s[sl-1]]>y[i]) do dec(sl);
if sl=0 then ns[i]:=-1 else ns[i]:=s[sl-1];
s[sl]:=i;inc(sl);
end;//栈优化
dec(b,x[1]);//把车开到第一站,自然需要花费x[1]单位的汽油
ans:=0;
for i:=1 to n do
if b<0 then begin//中途b<0时,必定开不到终点了
writeln(-1);
close(input);close(output);
halt;
end else begin
if ns[i]=-1 then gasn:=min(g,d-x[i]) else gasn:=min(g,x[ns[i]]-x[i]);
if gasn>b then begin//如果油有多的,则掏钱买
ans:=ans+(gasn-b)*y[i];
b:=gasn;
end;
if i=n then dec(b,d-x[i]) else dec(b,x[i+1]-x[i]);
end;
if b<0 then begin
writeln(-1);
close(input);close(output);
halt;
end else writeln(ans);
close(input);close(output);
end.
省钱加油(Fuel Economy)题解的更多相关文章
- 洛谷 P2209 [USACO13OPEN]燃油经济性Fuel Economy
P2209 [USACO13OPEN]燃油经济性Fuel Economy 题目描述 Farmer John has decided to take a cross-country vacation. ...
- P2209 [USACO13OPEN]燃油经济性Fuel Economy
题面 sol:(思想):开一个大根堆和一个小根堆,每次计算到下了一个加油站用掉的油时尽量用小根堆中的元素,且同时删去大根堆中的相应位置的元素,当前加油站如果足够便宜,就可以把大根堆中的元素替换掉: ( ...
- [luogu2209][USACO13]燃油经济性Fuel Economy_贪心
燃油经济性Fuel Economy 题目大意:FJ想要去旅行.他的车总容量为G,每行驶一个单位就消耗一个单位的油.FJ要行驶D个单位的距离.期间存在n个加油站,每个加油站有一个价格,表示在这个燃油站买 ...
- NOIP2017总结 & 题解
day1t1的结论貌似在哪见过,自己稍微验证了一下貌似没记错就没有管了.t2一道很好(keng)的模拟题啊t3自己做题好慢啊,想出来dp打上去最后几分钟才过了大样例,我写的是记忆化搜索,判-1很好判, ...
- 16.The Effect of Advertisement 广告的影响
16.The Effect of Advertisement 广告的影响 (1) The appeal of advertising to buying motives can have both n ...
- R语言-散点图进阶
1.分组散点图 ①xyplot()函数 > library(lattice) > xyplot(mpg~disp, #定义Y~X轴 + data=mtcars, + groups=cyl, ...
- 相关系数(CORRELATION COEFFICIENTS)会骗人?
CORRELATION COEFFICIENTS We've discussed how to summarize a single variable. The next question is ho ...
- 每日英语:Six Ways to Modernize Your Car
AS AUTO MAKERS ADD far-out features to the latest cars at warp speed--everything from futuristic hea ...
- [JAVASCRIPT][EXTJS]直接用JSON创建树形控件(Ext.tree.TreePanel )(转)
直接用JSON创建树形控件(Ext.tree.TreePanel ) 1.创建多个根节点的树形 2.直接使用JsonList创建树形 <!DOCTYPE HTML PUBLIC "-/ ...
随机推荐
- pyspark简要原则
概要 这是一个看前一段时间spark的python支持的时,有点简单的后pyspark内python代码,我们把一个一般流程.虽然几乎没有python,但基本上能看懂pyspark它是如何使不同的虚拟 ...
- [leetcode] Combination Sum and Combination SumII
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C wher ...
- String、StringBuffer和StringBuilder
一.String和StringBuffer String类型和StringBuffer类型的主要性能差别事实上在于String是不可变的对象,因此在每次对String类型进行改变的时候事实上都等同于生 ...
- cocos2D(五岁以下儿童)---- CCNode
本将主要介绍下CCNode这个类.CCNode是全部节点的基类,当中包含我们经常使用的CCScene(场景).CCLayer(图层).CCSprite(精灵)等.它是一个不可以可视化显示的抽象类,仅仅 ...
- SQL Server高可用——日志传送(4-2)——部署
原文:SQL Server高可用--日志传送(4-2)--部署 前文再续,书接上一回.本章演示一下日志传送的具体过程 准备工作: 由于时间关系,已经装好了3台虚拟机,且同在一个域里面: SQL01:主 ...
- Centos 7 静态学习IP建立
该研究主要集中在 Centos 7.0.1406 学习整理版! 1.编者 ifcfg-eth0 档,vim 同时尽量减少未安装安装,你并不需要自己安装叙述性说明. # vim /etc/sysconf ...
- SVN目录对号图标(更新、冲突)不显示
长谈想知道,大约SVN这些冲突.变化.加入.不显示问题etc目录下的复选图标,退房的在线信息,多数说的更改icon的settings,后来,一点点仔细阅读SVN配有英文说明文档,我相信,改变是有点问题 ...
- MKMapView移动事件地图
MKMapView移动事件地图 by 吴雪莹 -(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated { ...
- String.Format in Java and C#
原文:String.Format in Java and C# JDK1.5中,String类新增了一个很有用的静态方法String.format(): format(Locale l, String ...
- 变化Android系统属性SystemProperties.set("sys.powerctl", "shutdown")关机分析
基本介绍: 从以前的博客中提到,我们,最后,通过关机过程变化Android关机属性(SystemProperties.java由JNI呼叫接入系统属性),当然,我们也能adb命令变化Android系统 ...