题目

Problem description

一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位).每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距Di、每升汽油价格 Pi( i=l,2,...N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“-1”。

Input

输入数据的第一行是四个实数;

D1 C D2 P分别表示两个城市之间的距离,汽车油箱的容量,每升汽油能行驶的距离,出发点每升汽油格;

第二行是一个整数N,沿途的油站数。

第三行到第N+2,每一行是一个油站的基本信息描述,包括该油站离出发点的距离,该油站每升汽油的格。 Output

输出到达目的城市的最小费用(四舍五入到两位小数),若不能到达目的城市则输出 -1

Sample Input
275.6 11.9 27.4 2.8
2
102.0 2.9
220.0 2.2
Sample Output
26.95 Problem Source
// 测试用例
275.6 11.9 17.4 2.8
2
102.0 2.9
220.0 2.21
42.54 //
275.6 11.9 10.4 2.8
3
102.0 2.1
160.2 2.3
220.0 2.2
62.99

分析:

哨兵单元往往能够简化逻辑,减少判断和边界处理。在这道题中尤为明显。

我们把出发点当做距离为0,油价为p和普通油站放在一起;把目的地当做距离为s,油价为-1的油站跟普通油站放在一起。这样就得到了一个包含n+2个油站的数组。问题变得更加清楚简洁。

假如当前在第i个油站,那么唯一需要考虑的就是在这个油站需要加多少油。

这就需要考虑后面的油站:我只需要尽量保证我的油能够到达下一个比较便宜的油站即可。如果无法到达下一个便宜油站,那么我就需要加满油;如果我加满油依然无法到达下一个便宜的油站,那么我仍然需要加满油。

而经过“哨兵单元”处理,我们把目的地当做一个距离为s,油价为-1的油站放进了油站数组里面,所以我们一定能够找到下一个便宜的油站。这样就简化了逻辑。

如果潦草地写,这道题复杂度为$O(N^2)$,利用单调栈从左往右初始化每个元素的右面较小值,可以实现O(N)复杂度。

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner; public class Main {
class Point {
double dis, price; Point(double dis, double price) {
this.dis = dis;
this.price = price;
}
} Main() {
Scanner cin = new Scanner(System.in);
double s = cin.nextDouble(), c = cin.nextDouble(), d = cin.nextDouble(), p = cin.nextDouble();
int n = cin.nextInt();
Point[] a = new Point[n + 2];
for (int i = 0; i < n; i++) a[i] = new Point(cin.nextDouble(), cin.nextDouble());
a[n] = new Point(0, p);
a[n + 1] = new Point(s, -1);//终点的油是免费的
Arrays.sort(a, Comparator.comparing(x -> x.dis));
double money = 0, oil = 0, lastPos = 0;
for (int i = 0; i < a.length; i++) {
oil -= (a[i].dis - lastPos) / d;//剩余的油量
if (oil < 0) {
money = -1;
break;
}
if (a[i].price < 0) break;
int j = i + 1;
for (; j < a.length; j++) {
if (a[j].price < a[i].price) break;
}
double dis = a[j].dis - a[i].dis;
double need = dis / d;//到达下一站需要的油量
need = Math.min(c, need);
double add = need - oil;//现在需要加的油量
if (add > 0) {
money += add * a[i].price;
oil += add;
}
lastPos = a[i].dis;
}
if (money == -1) System.out.println(-1);
else {
long x = Math.round(money * 100);
System.out.println(x / 100 + "." + x % 100);
}
} public static void main(String[] args) {
new Main();
}
}

vijos:旅行家的预算[贪心]的更多相关文章

  1. P1016 旅行家的预算——贪心

    P1016 旅行家的预算 贪心求,在当前点如果能到达距离最近的油价比他小的就直接去油价比他小的, 如果在可行范围内没有比他油价小的,就加满开到可行范围内油价最小的点: 这么做是对的,我不会证明: 还有 ...

  2. [luogu]P1016 旅行家的预算[贪心]

    [luogu]P1016 旅行家的预算 题目描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的).给定两个城市之间的距离D1.汽车油箱的容量C(以升为单位).每升汽油能 ...

  3. 洛谷 P1016 旅行家的预算 模拟+贪心

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 总结 题面 题目链接 P1016 旅行家的预算 题目描述 一个旅行家想驾驶汽车 ...

  4. 洛谷 P1016 旅行家的预算

    P1016 旅行家的预算 题目OJ链接https://www.luogu.org/problemnew/show/P1016 题目描述一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时 ...

  5. 旅行家的预算(NOIP1999&水题测试2017082301)

    题目链接:旅行家的预算 这题还可以,不算太水. 这题贪心即可. 我们采取如下动作: 如果在装满油的情况下能到达的范围内,没有加油站,则无解. 如果在装满油的情况下能到达的范围内,油价最低的加油站的油价 ...

  6. codevs 1046 旅行家的预算

    传送门 1046 旅行家的预算 1999年NOIP全国联赛普及组NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold题解   题目描述 Des ...

  7. 蓝桥杯 算法训练 ALGO-15 旅行家的预算

    算法训练 旅行家的预算   时间限制:1.0s   内存限制:256.0MB 问题描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的).给定两个城市之间的距离D1.汽车 ...

  8. P1016 旅行家的预算

    P1016 旅行家的预算 题目描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的).给定两个城市之间的距离D1.汽车油箱的容量C(以升为单位).每升汽油能行驶的距离D2 ...

  9. LuoguP1016 旅行家的预算 (贪心)

    胡一个错误代码都能有75pts 忘了怎么手写deque其实是懒 #include <cstdio> #include <iostream> #include <cstri ...

随机推荐

  1. Matplotlib绘图双纵坐标轴设置及控制设置时间格式

    双y轴坐标轴图 今天利用matplotlib绘图,想要完成一个双坐标格式的图. fig=plt.figure(figsize=(20,15)) ax1=fig.add_subplot(111) ax1 ...

  2. 编译GSLSDevil的全过程

      GLSLDevil是调试OpenGL程序的工具. GLSLDevil的新版本已经改名为GLSL-Debugger, github的地址在这里:http://glsl-debugger.github ...

  3. WIFI:802.11协议帧格式

    802协议桢格式 802.11和Wi-Fi技术并不是同一个东西.Wi-Fi标准是802.11标准的一个子集,并且是Wi-Fi联盟负责管理 802协议桢格式: 协议 发布年份/日期 Op.标准频宽 实际 ...

  4. Android中创建option menu

    1.首先在res目录下新建一个menu文件夹,右击res目录->New->Directory,输入文件夹名menu,点击OK. 接着在这个文件夹下再新建一个名叫main的菜单文件,右击me ...

  5. Selenium2(WebDriver)总结(一)---启动浏览器、设置profile&加载插件

    本文主要记录下在使用selenium2/webdriver时启动各种浏览器的方法.以及如何加载插件.定制浏览器信息(设置profile)等 环境搭建可参考我的另一篇文章:http://www.cnbl ...

  6. js - 关于循环

    ES5:for,foreach,for..in ES6:for..of // ES5(可参见ES6的析构写法) const value = ["a", "b", ...

  7. Shiro整合springboot,freemaker,redis(含权限系统完整源码)

    区块链技术联盟 2018-02-08 17:06:40 目录 一.导语 二.shiro功能介绍 三.shiro详解 四.shiro实战案例分享 五.系统配置 六.其他 一.导语 今天推荐给大家一个非常 ...

  8. Android View的事件分发机制

    准备了一阵子,一直想写一篇事件分发的文章总结一下.这个知识点实在是太重要了. 一个应用的布局是丰富的,有TextView,ImageView,Button等.这些子View的外层还有ViewGroup ...

  9. 路由器mtu值设置

    MTU=最大传输单元 单位:字节 英文:Maximum Transmission Unit”我们平时上网时的各种操作,都是通过一个又一个“数据包”传输来实现的.而MTU指定了网络中可传输数据包的最大尺 ...

  10. Python locale error: unsupported locale setting

    pip don't install package. Python locale error: unsupported locale setting .. >>> import lo ...