Java实现蓝桥杯 算法训练 ALGO-15 旅行家的预算
问题描述
  一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离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 旅行家的预算的更多相关文章
- Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
		
试题 算法训练 猴子吃包子 问题描述 从前,有一只吃包子很厉害的猴子,它可以吃无数个包子,但是,它吃不同的包子速度也不同:肉包每秒钟吃x个:韭菜包每秒钟吃y个:没有馅的包子每秒钟吃z个:现在有x1个肉 ...
 - Java实现蓝桥杯 算法训练 大等于n的最小完全平方数
		
试题 算法训练 大等于n的最小完全平方数 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 输出大等于n的最小的完全平方数. 若一个数能表示成某个自然数的平方的形式,则称这个数为完全平 ...
 - Java实现 蓝桥杯 算法训练 画图(暴力)
		
试题 算法训练 画图 问题描述 在一个定义了直角坐标系的纸上,画一个(x1,y1)到(x2,y2)的矩形指将横坐标范围从x1到x2,纵坐标范围从y1到y2之间的区域涂上颜色. 下图给出了一个画了两个矩 ...
 - Java实现 蓝桥杯 算法训练 Lift and Throw
		
试题 算法训练 Lift and Throw 问题描述 给定一条标有整点(1, 2, 3, -)的射线. 定义两个点之间的距离为其下标之差的绝对值. Laharl, Etna, Flonne一开始在这 ...
 - Java实现 蓝桥杯 算法训练 Airport Configuration
		
试题 算法训练 Airport Configuration 问题描述 ACM机场是一个本地机场,对于大多数人来说,机场不是他们的终点或起点,而是中转站.机场有一个规划图.到达的大门在机场的北边(相当于 ...
 - Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
		
试题 算法训练 Rotatable Number 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 Bike是个十分喜欢数学的聪明孩子.他发明了"可旋转数",其灵感 ...
 - Java实现 蓝桥杯 算法训练 最大的算式
		
算法训练 最大的算式 时间限制:1.0s 内存限制:256.0MB 问题描述 题目很简单,给出N个数字,不改变它们的相对位置,在中间加入K个乘号和N-K-1个加号,(括号随便加)使最终结果尽量大.因为 ...
 - Java实现蓝桥杯 算法训练 Professor Monotonic's Network
		
试题 算法训练 Professor Monotonic's Network 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 无聊的教授最近在做一项关于比较网络的实验.一个比较网络由若 ...
 - Java实现 蓝桥杯 算法训练 1的个数
		
试题 算法训练 1的个数 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 输入正整数n,判断从1到n之中,数字1一共要出现几次.例如1123这个数,则出现了两次1.例如15,那么从1 ...
 - java实现 蓝桥杯 算法训练 Password Suspects
		
问题描述 在年轻的时候,我们故事中的英雄--国王 Copa--他的私人数据并不是完全安全地隐蔽.对他来说是,这不可接受的.因此,他发明了一种密码,好记又难以破解.后来,他才知道这种密码是一个长度为奇数 ...
 
随机推荐
- JPA---Spring-data-JPA---Hibernate
			
Spring Data JPA--搭建环境 版本---maven 3.6.3 <properties> <spring.version>5.2.5.RELEASE</s ...
 - C#MVC通过AJAX调用API方法进行上传下载
			
//这是写的一个类,具体是上传图片的上传和下载 public class FileResult { public int Code { get; set; } pub ...
 - FPGA学习心得汇总(手中写代码,心中有电路)
			
http://bbs.ednchina.com/BLOG_ARTICLE_2111172.HTM 任何的时序逻辑都可以转换为组合逻辑+D触发器来完成. FPGA内部主要三块:可编程的逻辑单元.可编程的 ...
 - [hdu1079]简单博弈
			
题意:两个人玩游戏,给定一个日期,他们轮流选择日期,可以选择当前日期的下一天,如果下一个月也有这一天的话则也可以选择下一个月的这一天.超过某一日期的人输. 思路:以天为状态,则一共有300多万个左右的 ...
 - Go中操作mysql
			
Go中操作mysql 首先在mysql里的test数据库中创建数据表 CREATE TABLE `userinfo` ( `uid` INT(10) NOT NULL AUTO_INCREMENT, ...
 - SQL 选择列 IF表达式,Contains表达式的用法
			
因为业务需要需要使用到, 列中的字段或根据列值是否满足某一条件,进行输出.比如类似与 select if() ……from……:(但是SQL Server 没有 if 表达式) 比如,如果Scor ...
 - 线程和Python—Python多线程编程
			
线程和Python 本节主要记录如何在 Python 中使用线程,其中包括全局解释器锁对线程的限制和对应的学习脚本. 全局解释器锁 Python 代码的执行是由 Python 虚拟机(又叫解释器主循环 ...
 - ios上表单默认样式
			
摘自:http://blog.sina.com.cn/s/blog_7d796c0d0102uyd2.html 可惜不能直接转到博客园. input[type="button"], ...
 - Rabbitmq 报错 nodedown
			
问题描述 线上 rabbitmq 集群账号密码设置的过于简单,有一定的风险.在整改过程中发现,三台机器信息错乱,每台服务器执行rabbitmq 相关的命令就报错,Error: unable to co ...
 - 2-SAT问题简述
			
前置知识 强连通分量 k-SAT问题 k-SAT问题中的SAT意思就是(stability),也就是适应性问题.本意是给出n个变量,每一个变量有k个状态,并且也给出一些约束条件,要求你求出是否存在每一 ...