0
点赞
收藏
分享

微信扫一扫

2021.06.02旅行家的预算

ivy吖 2022-03-25 阅读 35

2021.06.02旅行家的预算

题目描述

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

输入格式

第一行,D1,C,D2,P,N。

接下来有N行。

第i+1行,两个数字,油站i离出发点的距离Di和每升汽油价格Pi。

输出格式

所需最小费用,计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

样例输入

275.6 11.9 27.4 2.8 2
102.0 2.9
220.0 2.2

样例输出

26.95

数据规模和约定

N≤6,其余数字≤500

思路

思路1:dfs

由于规模较小,可以直接搜索。

思路2:贪心+模拟

  1. 贪心策略如下:

     if(加满油可到达范围内有价格更低的加油站) {
         加刚好到那儿的油;
     } 
     else if(加满油可到达范围内没有价格更低的加油站) {
         加满油;
         去范围内价格最低的加油站;
     }
    
  2. 细节考虑:
    为了将起点和重点纳入考虑,可以定义一个长度为n+2的数组,并且将终点看成一个油费为0,且dis == D的加油站。(因为在贪心策略中是优先到达油费低的加油站的。)

思路2:代码

    class Solution{ 
        void test() {
            Scanner cin = new Scanner(System.in);
            double D = cin.nextDouble();
            double C = cin.nextDouble();
            double d = cin.nextDouble();
            double p = cin.nextDouble();
            int n = cin.nextInt();
            Station[] sta = new Station[n+1+1];
            for(int i = 1; i <= n; i++) 
                sta[i] = new Station(cin.nextDouble(), cin.nextDouble(), i);
            sta[0] = new Station(0, p, 0);
            sta[n+1] = new Station(D,0,0);
            // *********************** i/o ************************
            double s = 0; double tol = C*d; double remain = 0;
            for(int i = 0; i < sta.length-1; i++) { //判断能否到达
                if(sta[i+1].dis-sta[i].dis > tol) {
                    System.out.println("No Solution");
                    return;
                }
            }
            if(n == 0) { //判特
                if(D > tol) System.out.println("No Solution");
                else System.out.printf("%.2f",(D*p)/d);
                return;
            } 
            for(int i = 0; i <= n; i++) {
                int lowInd = -1;
                for(int j = i+1;  j < sta.length && sta[i].dis+tol >= sta[j].dis ; j++) {
                    if(sta[j].price < sta[i].price) {
                        lowInd = j;
                        break;
                    }
                }
                if(lowInd == -1) { //在范围内没有比他价格低的,找范围内相对低的
                    //先把油加满
                    s += sta[i].price*(C-remain);
                    double lowP = Double.MAX_VALUE;
                    for(int j = i+1; j < sta.length && sta[i].dis+tol >= sta[j].dis; j++) {
                        if(sta[j].price < lowP) lowInd = j;
                    }
                    remain = C- (sta[lowInd].dis-sta[i].dis)/d;
                    i = lowInd-1;
                } else { //在范围内有比他更低的,去那。
                    double need = (sta[lowInd].dis-sta[i].dis)/d;
                    //必定有remain < need,否则在上一步就已经达到此价格更低加油站了
                    s += sta[i].price*(need-remain);
                    remain = 0;
                    i = lowInd-1;
                }
            }
            System.out.printf("%.2f",s);
        }
    }
    class Station{
        double dis,price;
        int i;
        public Station(double dis, double price, int i) {
            super();
            this.dis = dis;
            this.price = price;
            this.i = i;
        }
    }
举报

相关推荐

0 条评论