问题描述
  一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,……N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。
输入格式
  第一行为4个实数D1、C、D2、P与一个非负整数N;
  接下来N行,每行两个实数Di、Pi。
输出格式
  如果可以到达目的地,输出一个实数(四舍五入至小数点后两位),表示最小费用;否则输出“No Solution”(不含引号)。
样例输入
275.6 11.9 27.4 2.8 2
102.0 2.9
220.0 2.2
样例输出
26.95

思路:还是要先吐槽一下,好多网上的教程都是错的啊,什么直接走到头然后不能走了在当前的加油站加上油到下一个加油站就行,感觉根本就是欺负蓝桥杯的数据规模。事实上这个题完全想清楚还是不太容易的。下面讲题。

我们先分析数据知道,加油站有位置,油价。然后车的油箱有容量,猛一想并不是直接就能相通如何找到停留点的,具体看下面的分析。

我们先分析一下需要什么变量,车有可能有油,有可能没油,所以需要一个变量记录油箱剩下多少油。然后我们想一下,如果当前在第i个加油站,而只有行驶到第i+k个加油站油价更便宜,那么肯定停下在i+k点加油比较合算,那么我们肯定就要记录每次停下的位置(因为后面分析是贪心,贪心的思想就是将一个线段分成几份走完,局部最优求整体最优。)

首先确定如何判断无法到达目的地的情况:我们知道 车辆不加油的最大行驶距离== (油箱容量)c * (每升油的行驶距离)d2 那么当存在相邻两个加油站的间距比车辆不加油的最大行驶距离还大的话,到目标点是不可能完成的。

然后我们分析一下车辆的行驶情况

1.假如当前点为i,在车辆不加油的最大行驶距离内存在第i+k处油价更低
(1)油箱内剩余的油可以到达该位置
这种情况我们直接用剩下的油跑到i+k点就可以了,不花钱肯定是最节省的!

(2)油箱内剩余的油不够到达该位置
在这种情况是肯定是要加油的,而且无疑我们肯定是加当前点i的油是最划算的。那么应该加多少呢?加上油刚刚好到达i+k点是最好的! 因为i+k的油比i的油便宜,没必要在i位置多加油,如果后面需要在i+k加更划算。

2.假如当前点为i,在车辆不加油的最大行驶距离内不存在第i+k处油价更低
这个时候怎么办!我们加满油去跑一定划算,因为以i为起点在车辆不加油的最大行驶距离内 行驶一定找不到价格更低的加油站,我们一定是在价格相对最低的地方加油比较好。具体加油的多少还要看下一步能不能到更便宜的加油站,如果有参考1行进,如果没有继续参考2行进。

然后我的代码有一些特点,首先变量名比较长啊…海涵…然后是用结构体记录的第0位置是起点,第n+1位置是终点,终点的油价变量我设为0,可以理解为最便宜的,所以程序一定回到n+1点去!为什么说这个在程序实现的过程中就能体会到了。

我的具体代码基本上都注释了,如果有不明白的欢迎提问!

这篇文章原c++编写的,我也是小白
原文在:
https://blog.csdn.net/qq_35078631/article/details/62897099

import java.util.Scanner;public class Main{static double a []; //位置static double b [];//油价static double last_oil;        //油箱剩余空间static double run_c;           //剩余油料可以行走的最大距离static int    best_pos;        //形成内最小油料价格的位置 static double full_run;        //邮箱在满了的情况下可以跑多远 static double use=0;static double d1,c,d2,p;static int n;public static void main(String[] args) {Scanner sc = new Scanner(System.in);d1=sc.nextDouble();c=sc.nextDouble();d2=sc.nextDouble();p=sc.nextDouble();n=sc.nextInt();a=new double [n+2];b=new double [n+2];for (int i = 1; i <=n; i++) {a[i]=sc.nextDouble();b[i]=sc.nextDouble();}a[0]=0;a[n+1]=d1;b[0]=p;b[n+1]=0;last_oil=0;             //初始化邮箱剩余油量 best_pos=0;             //初始化初始位置 full_run=c*d2;for(int i=0;i<=n;i++){  //验证是否可达 if(a[i+1]-a[i]>full_run){System.out.println("No Solution");}}run();System.out.println((use));}public static void run(){if(best_pos==n+1) return ;int flag=0;         //标记在最大行程内有没有找到费用更少的收费站 run_c=last_oil*d2;for(int i=best_pos+1;i<=n+1;i++){if(a[i]-a[best_pos]<=full_run){             //必须在full_run范围之内 if(b[i]<=b[best_pos]){              //如果是更优的选择 flag=1;                                     //标记 if(run_c>=a[i]-a[best_pos]){        //如果剩下的油已经够跑了 last_oil=(a[i]-a[best_pos])/d2; //剩余油量更新}else{                                       //如果剩下的油不够跑 last_oil=0;                             //要恰好跑到价格更低的加油站 use+=(a[i]-a[best_pos]-run_c)/d2*b[best_pos];}best_pos=i;                                 //更新最优节点 break;} }}if(flag==0){                                //没有匹配到最优解 int better_pos=best_pos+1;for(int i=best_pos+1;i<=n+1;i++){       //一定是不可能到n+1的,因为n+1的在上面是一定可以匹配的!因为a[n+1].price是0! if(a[i]-a[best_pos]<=full_run){if(b[i]<b[better_pos]){better_pos=i;}}}//找到了更优值use+=(c-last_oil)*b[best_pos];                //一定是加满油最好了!因为在满油的行车范围内都到不了最优的,所以一定要加满油 last_oil=c-(a[better_pos]-a[best_pos])/d2;  //先更新到达better_pos位置剩下的油料 best_pos=better_pos;} run(); }
}

Java实现蓝桥杯 算法训练 ALGO-15 旅行家的预算相关推荐

  1. Java实现 蓝桥杯 算法训练 删除数组零元素

    算法训练 删除数组零元素 时间限制:1.0s 内存限制:512.0MB 提交此题 从键盘读入n个整数放入数组中,编写函数CompactIntegers,删除数组中所有值为0的元素,其后元素向数组首端移 ...

  2. Java实现 蓝桥杯 算法训练 Balloons in a Box

    试题 算法训练 Balloons in a Box 问题描述 你要写一个程序,使得能够模拟在长方体的盒子里放置球形的气球. 接下来是模拟的方案.假设你已知一个长方体的盒子和一个点集.每一个点代表一个可 ...

  3. Java实现 蓝桥杯 算法训练 相邻数对(暴力)

    试题 算法训练 相邻数对 问题描述 给定n个不同的整数,问这些数中有多少对整数,它们的值正好相差1. 输入格式 输入的第一行包含一个整数n,表示给定整数的个数. 第二行包含所给定的n个整数. 输出格式 ...

  4. Java实现 蓝桥杯 算法训练 Beaver's Calculator

    试题 算法训练 Beaver's Calculator 问题描述 从万能词典来的聪明的海狸已经使我们惊讶了一次.他开发了一种新的计算器,他将此命名为"Beaver's Calculator ...

  5. Java实现 蓝桥杯 算法训练 未名湖边的烦恼

    算法训练 未名湖边的烦恼 时间限制:1.0s 内存限制:256.0MB 问题描述 每年冬天,北大未名湖上都是滑冰的好地方.北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩. ...

  6. Java实现 蓝桥杯 算法训练 天数计算

    试题 算法训练 天数计算 问题描述 编写函数求某年某月某日(**** ** **)是这一年的第几天 .提示:要考虑闰年,闰年的2月是29天(闰年的条件:是4的倍数但不是100的倍数,或者是400的倍数 ...

  7. Java实现 蓝桥杯 算法训练 Cowboys

    试题 算法训练 Cowboys 问题描述 一个间不容发的时刻:n个牛仔站立于一个环中,并且每个牛仔都用左轮手枪指着他旁边的人!每个牛仔指着他顺时针或者逆时针方向上的相邻的人.正如很多西部片那样,在这一 ...

  8. Java实现 蓝桥杯 算法训练 字串统计

    算法训练 字串统计 时间限制:1.0s 内存限制:512.0MB 问题描述 给定一个长度为n的字符串S,还有一个数字L,统计长度大于等于L的出现次数最多的子串(不同的出现可以相交),如果有多个,输出最 ...

  9. Java实现 蓝桥杯 算法训练 My Bad(暴力)

    试题 算法训练 My Bad 问题描述 一个逻辑电路将其输入通过不同的门映射到输出,在电路中没有回路.输入和输出是一个逻辑值的有序集合,逻辑值被表示为1和0.我们所考虑的电路由与门(and gate, ...

最新文章

  1. 人工智能和自然智能能否交汇?李飞飞对话斯坦福神经生物学教授Bill Newsome
  2. 数据库笔记: SQL
  3. SOCKADDR_IN
  4. 连表查询使用in_SQL 组合查询
  5. C# 按部门拆分excel文件
  6. 常用标准库_C语言标准IO库常用函数
  7. Sublime Text 3实用快捷键大全
  8. shl性格测试_德勤2021秋招网申Tips+SHL笔试原题
  9. 与基础事务管理器的通信失败 存货申请_干货必读!细说分布式事务两阶段提交...
  10. JSOI 2008 【魔兽地图】
  11. Leetcode 133.克隆图
  12. c语言根据元素位置读取元素,jquery1.5.1中根据元素ID获取元素对象的代码
  13. 用R语言做单方程的误差修正模型(ECM)
  14. UG NX二次开发(C#)-同步建模-删除倒圆(圆角)
  15. 漏洞补丁:windwos补丁下载(MS17-010)
  16. 「3D建模」建模中什么是重新拓补?为什么要拓补,有何作用?
  17. visio画箭头时,如何去掉箭头的自动连接连接点(吸附)功能?
  18. 微信小程序 | 微信公众平台SpringBoot开发实例 │ 表情消息
  19. OC内存管理常见面试题整理
  20. java-php-python-ssm商超销售系统计算机毕业设计

热门文章

  1. Yolo实用指南(step by step)之三yolov5训练自己的数据集
  2. 小白学习Python的第十六天之正则表达式
  3. 机器人皮肤:气球和废纸都能有生命!万物皆有成为生命的可能!
  4. 如何用代码实现抖音的图片旋转
  5. JiangxiBank
  6. leetcode 974 Subarray Sums Divisible by K
  7. ZOJ1845 Australian Voting
  8. c语言程序ax2 bx,计算ax2+bx+c程序清单计算机组成原理计算机系统概论.PPT
  9. pytorch:如何从头开始训练一个CNN网络?
  10. 如何减少http请求的次数