贪心算法-汽车加油

这道题目描述了一个汽车旅行场景,需要设计一个有效的算法来决定在哪几个加油站停车加油,以便最小化加油次数。题目给出了汽车加满油后的行驶距离n公里,以及沿途若干个加油站的位置。我们需要找出一个方案,使得汽车能够完成整个旅程,同时加油次数最少。

为了更好地理解并解决问题,我们可以将其转化为数学模型和算法设计问题。首先,明确以下几个关键点:

  1. 汽车的行驶能力:汽车加满油后可以行驶n公里。
  2. 加油站分布:沿路有k个加油站,每个加油站的具体位置已知。
  3. 目标:找到一条路线,使得汽车能够完成全程,同时加油次数最少。

解决方案

我们可以使用贪心算法来解决这个问题。贪心策略的基本思想是从局部最优解入手,一步步构造全局最优解。在这里,我们的局部最优决策就是每次选择离当前位置最远的那个加油站作为下一个加油地点。

步骤如下:

  1. 初始化变量

    • 当前位置设为起点。
    • 加油次数计数器置零。
  2. 迭代过程

    • 遍历所有的加油站,寻找离当前位置最远但又不会超过汽车行驶范围的加油站。
    • 如果找到了这样的加油站,就在那里加油,并更新当前位置。
    • 同时,加油次数计数器加一。
  3. 结束条件

    • 如果没有找到合适的加油站,说明当前油量不足以达到任何一个加油站,返回“No Solution”。
    • 如果已经到达终点,停止搜索。

实现细节

  • 数据结构:可以用一个列表或数组来保存加油站的位置。
  • 算法流程:按照上述步骤编写程序逻辑,需要注意的是,在每次选择加油站之后,都要检查是否还能到达下一个加油站,否则就需要再次加油。

注意事项

  • 确保加油站的位置是按顺序排列的,这样可以简化查找过程。
  • 在实际编码过程中,要注意边界条件的处理,避免出现越界错误。

通过这种方法,我们可以有效地解决这个问题,找到最少加油次数的方案。如果在某一步发现无法前进,那么就表明没有可行的解决方案,此时应返回“No Solution”。

假设我们有一个int[] gasStations数组,它包含了从起点到终点所有加油站的位置(公里数),并且汽车加满油后能行驶的最大距离为int maxDistance。我们将从起点开始尝试到达终点,途中尽可能少地加油。

import java.util.Arrays;

public class MinimumRefuelStops {
    public static void main(String[] args) {
        int maxDistance = 10; // 汽车加满油后能行驶的最大距离
        int[] gasStations = {2, 5, 7, 10}; // 加油站位置,单位为公里
        int destination = 10; // 目的地的位置
        
        System.out.println(minimumRefuelStops(maxDistance, gasStations, destination));
    }

    /**
     * 计算最少加油次数。
     *
     * @param maxDistance 汽车加满油后能行驶的最大距离
     * @param gasStations 加油站位置数组
     * @param destination 目的地的位置
     * @return 最少加油次数,若无法到达目的地则返回"No Solution"
     */
    public static String minimumRefuelStops(int maxDistance, int[] gasStations, int destination) {
        int currentPosition = 0; // 当前位置
        int refuelCount = 0; // 加油次数
        int nextStationIndex = 0; // 下一个加油站的索引

        while (currentPosition < destination) {
            // 找到最远可以到达的加油站
            while (nextStationIndex < gasStations.length && gasStations[nextStationIndex] <= currentPosition + maxDistance) {
                nextStationIndex++;
            }

            // 如果当前位置已经超过了最后一个加油站,但仍未到达目的地
            if (nextStationIndex == gasStations.length && currentPosition + maxDistance < destination) {
                return "No Solution";
            }

            // 如果当前位置已经可以到达或超过目的地
            if (currentPosition + maxDistance >= destination) {
                break;
            }

            // 如果有可用的加油站,选择最远的一个加油
            if (nextStationIndex > 0) {
                currentPosition = gasStations[nextStationIndex - 1];
                refuelCount++;
            } else {
                // 没有可以到达的加油站
                return "No Solution";
            }
        }

        return String.valueOf(refuelCount);
    }
}

这段代码中,我们定义了一个minimumRefuelStops方法来计算最少加油次数。该方法首先初始化当前位置和加油次数,然后在一个循环中不断寻找最远可以到达的下一个加油站,直到汽车能够到达目的地或者确定无法到达目的地为止。

注意,这个例子假设了gasStations数组中的元素已经按照从小到大的顺序排序,这是合理的,因为加油站的位置应该是沿着路径递增的。如果实际情况不是这样,您可能需要先对gasStations数组进行排序。

在每次决定是否加油时,贪心算法会选择在当前油量不足以到达下一个加油站或目的地时才进行加油。这种选择保证了每次加油都是必要的,避免了不必要的加油操作,从而减少了总的加油次数。

package tanxin;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class CarsStop {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int n = scanner.nextInt(); // 输入加满油可行驶的公里数
        int k = scanner.nextInt(); // 输入加油站数量

        int[] distances = new int[k + 1]; // 定义数组存储相邻加油站之间的距离,最后一个元素是最后一个加油站到目的地的距离
        for (int i = 0; i < k; i++) {
            distances[i] = scanner.nextInt(); // 读取相邻加油站之间的距离
        }
        distances[k] = scanner.nextInt(); // 最后一个加油站到目的地的距离

        int m = 0; // 初始化加油次数为0
        int t = n; // 汽车开始可行驶的公里数
        List<Integer> stations = new ArrayList<>(); // 存储加油的加油站编号

        for (int i = 0; i <= k; i++) { // 包括最后一个加油站到目的地的距离
            if (distances[i] > n) { // 如果某段距离大于汽车的最大行驶距离,输出无解并退出程序
                System.out.println("No Solution");
                return;
            }
            if (t < distances[i]) { // 如果当前剩余油量不足以到达下一个地点,则需要加油
                
                t = n; // 汽车加一次油,汽车能行驶的距离变为n
                m++; // 加油次数+1
                stations.add(i - 1); // 记录加油的加油站编号,注意这里是i-1因为是在到达i站之前加油
            }
            t -= distances[i]; // 减去已行驶的距离
        }

        System.out.println("加油次数为:" + m); // 输出加油次数
        if (!stations.isEmpty()) {
            System.out.print("加油地点:");
            for (Integer station : stations) {
                System.out.print("第" + (station + 1) + "个加油站, ");
            }
            System.out.println(); // 换行
        }
    }
}
  1. 输入读取

    • 首先,程序通过 Scanner 类读取用户输入的数据。包括汽车加满油后可以行驶的最大距离 n 和加油站的数量 k
    • 然后,程序读取每个加油站之间的距离(存入 distances 数组),以及最后一个加油站到目的地的距离。
  2. 初始化变量

    • m 变量用于记录加油次数,初始值为0。
    • t 变量代表汽车当前还剩多少公里可以行驶,初始值为 n,即汽车加满油后的最大行驶距离。
    • stations 列表用来存储每次加油时所在的加油站编号。
  3. 核心逻辑

    • 使用一个循环遍历所有加油站的距离数据,包括从最后一个加油站到目的地的距离。
    • 对于每一个距离 distances[i],首先检查该距离是否超过了汽车的最大行驶距离 n,如果是,则输出“无解”并结束程序。
    • 接着,判断当前剩余油量 t 是否足够行驶至下一个加油站或目的地。如果不够,则需要在当前加油站加油,并更新相关变量:
      • 将 t 重置为 n,表示汽车加满油后能行驶的最大距离。
      • 增加加油次数 m
      • 记录加油的加油站编号 i - 1 到 stations 列表中(注意这里是因为加油是在到达下一个加油站之前完成的)。
    • 更新 t,减去已经行驶过的距离 distances[i]
  4. 输出结果

    • 循环结束后,输出总的加油次数 m
    • 如果有加油记录,还会输出具体的加油地点。

示例运行

假设输入如下:

7 7
1 2 3 4 5 1 6 1

这表示汽车加满油后可以行驶的最大距离为7公里,总共有7个加油站,各加油站间的距离分别为1, 2, 3, 4, 5, 1公里,最后一个加油站到目的地的距离为6公里。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/913674.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Docker#2] 发展历史 | Namespace环境隔离 | Cgroup资源控制

目录 1.发展历史 Jail 时代 云时代 云原生时代 技术标准的确立 虚拟机 vs Docker 2. 容器化技术 2.1 Namespace 命令详解 1. dd 命令 2. mkfs 命令 3. df 命令 4. mount 命令 5. unshare 命令 实战 进程隔离 文件隔离 2.2 CGroup 相关命令 2.1 pidstat 2.…

【Ubuntu学习】Ubuntu无法使用vim命令编辑

问题 在VMware首次安装Ubuntu&#xff0c;使用vi指令对文件进行编辑&#xff0c;按i键后无法更改文件内容。 原因 由于Ubuntu中预装的是vim-tiny&#xff0c;平时开发中需要使用vim-full。 解决方案 卸载预装vim sudo apt-get remove vim-common安装vim-full sudo apt-get …

同轴全息图和离轴全息图

一、同轴全息图 1.1 记录 设透明的物体(相位物)的振幅透过率为: t0是一个很高的平均透射率,表示围绕平均值的变化。 透射光场可以看成由两项组成: 一项是由t0表示的强而均匀的平面波, 它相当于波前记录时的参考波, 另一 项是Δt 所代表的弱散射波, 它相当于波前记录时的物光波…

Redhat切换其他源

1. 效果图 2. 安装 RPM 包的命令 rpm -ivh --nodeps --force epel-release-latest-8.noarch.rpm rpm -ivh --nodeps --force yum-4.7.0-4.el8.noarch.rpm rpm -ivh --nodeps --force yum-utils-4.0.21-3.el8.noarch.rpm 3. 修改默认源 vi /etc/yum.repos.d/redhat.repo[BaseO…

SpringMVC学习记录(三)之响应数据

SpringMVC学习记录&#xff08;三&#xff09;之响应数据 一、页面跳转控制1、快速返回模板视图2、转发和重定向 二、返回JSON数据1、前置准备2、ResponseBody 三、返回静态资源1、静态资源概念2、访问静态资源 /*** TODO: 一个controller的方法是控制层的一个处理器,我们称为h…

MethodChannel的用法

文章目录 1 知识回顾2 示例代码3 经验总结我们在上一章回中介绍了MethodChannel的使用方法,本章回中将介绍EventChannel的使用方法.闲话休提,让我们一起Talk Flutter吧。 1 知识回顾 我们在前面章回中介绍了通道的概念和作用,并且提到了通道有不同的类型,本章回将其中一种…

[每周一更]-(第122期):模拟面试|数据库面试思路解析

10|数据库索引:为什么 MySQL 用 B+ 树而不用 B 树? 为什么 MySQL 用 B+ 树而不用 B 树? 什么是覆盖索引? 什么是聚簇索引/非聚簇索引? 什么是哈希索引?MySQL InnoDB 引擎怎么创建一个哈希索引? 什么回表?如何避免回表? 树的高度和查询性能是什么关系? 什么是索引最左…

React的概念以及发展前景如何?

React是一个由Facebook开发的用于构建用户界面的的开源JavaScript库&#xff0c;它主要用于构建大型、动态的Web应用程序。React的主要特点是使用VirtualDOM&#xff08;虚拟DOM&#xff09;来优化性能&#xff0c;并使用声明式的编程方式来编写UI。 React的主要概念包括&#…

【Spring编程常见错误50例】03.依赖注入常见错误-上

1.多个实现类 如何匹配 在实际的开发中&#xff0c;我们会使用Autowired 注解进行依赖注入对应的bean&#xff0c;但是如果我们依赖的是一个接口&#xff0c;有对应多个实现的话&#xff0c;就会出现异常。 RestController public class DbController {Autowiredprivate DbSe…

智能母线插接箱监测装置的工作原理与实际应用分析

徐悦 安科瑞电气股份有限公司 随着电力系统的智能化发展&#xff0c;如何有效地监控电力系统的运行状态并保证系统安全性&#xff0c;成为电力运维中不可忽视的问题。AMB100智能母线直流监控装置应运而生。本文将详细介绍AMB100的工作原理及技术特点&#xff0c;结合实际应用…

USB包的结构

本文章主要来自《圈圈教你玩USB》的学习笔记 USB包的结构 USB是串行总线&#xff0c;所以数据是一位位的在数据总线上传输&#xff0c;采用LSB在前的方式。 USB数据需要经过位填充和NRZI编码。在这里讨论时&#xff0c;所用的数据都是原始数据&#xff0c;即没有经过位填充和…

让redis一直开启服务/自动启动

文章目录 你的redis是怎么打开的黑窗不能关?必须要自动启动吗?再说说mysql 本文的所有指令都建议在管理员权限下打开cmd控制台 推荐的以管理员身份打开控制台的方式 Win R 打开运行 输入cmdShift Ctrl Enter 你的redis是怎么打开的 安装过redis的朋友都知道, redis的安…

吴恩达深度学习笔记:卷积神经网络(Foundations of Convolutional Neural Networks)4.11

目录 第四门课 卷积神经网络&#xff08;Convolutional Neural Networks&#xff09;第四周 特殊应用&#xff1a;人脸识别和神经风格转换&#xff08;Special applications: Face recognition &Neural style transfer&#xff09;4.11 一维到三维推广&#xff08;1D and 3…

基于图的去中心化社会推荐过滤器

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年11月11日19点20分 点击开启你的论文编程之旅https://www.aspiringcode.com/content?id17176636216843&uideba758a1550b46bb…

云计算在教育领域的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 云计算在教育领域的应用 云计算在教育领域的应用 云计算在教育领域的应用 引言 云计算概述 定义与原理 发展历程 云计算的关键技…

开始使用 Elastic AI Assistant 进行可观察性和 Microsoft Azure OpenAI

作者&#xff1a;Jonathan Simon 按照此分步过程开始使用 Elastic AI Assistant for Observability 和 Microsoft Azure OpenAI。 最近&#xff0c;Elastic 宣布&#xff0c;AI Assistant for Observability 现已面向所有 Elastic 用户开放。AI Assistant 为 Elastic Observabi…

uniapp—android原生插件开发(1环境准备)

本篇文章从实战角度出发&#xff0c;将UniApp集成新大陆PDA设备RFID的全过程分为四部曲&#xff0c;涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程&#xff0c;轻松应对安卓原生插件开发与打包需求&#xff01; 项目背景&#xff1a; UniApp集成新大陆P…

git新手使用教程

git新手使用教程 一、安装和初始化配置2、新建仓库3.工作区域和文件状态4.添加和提交文件5 git reset回退版本6 使用git diff查看差异7 使用git rm删除文件8 .gitignore忽略文件9 注册GitHub账号10 SSH配置和克隆仓库11 关联本地仓库和远程仓库12 Gitee的使用 由B站视频教程整理…

java程序优化二

接触渲染也有一段时间了&#xff0c;发现还有很多优化的空间&#xff0c;今天时间比较有限就提一点 一&#xff1a;从参数接口方面&#xff0c;例如提交渲染接口参数有大量的浮点数据&#xff0c;小数位过多&#xff0c;其实四舍五入保留4位也没什么影响&#xff0c;这样大小接…

分布式----Ceph部署(上)

目录 一、存储基础 1.1 单机存储设备 1.2 单机存储的问题 1.3 商业存储解决方案 1.4 分布式存储&#xff08;软件定义的存储 SDS&#xff09; 1.5 分布式存储的类型 二、Ceph 简介 三、Ceph 优势 四、Ceph 架构 五、Ceph 核心组件 #Pool中数据保存方式支持两种类型&…