Vijos 1253 旅行家的预算

来源:互联网 发布:数据采样 编辑:程序博客网 时间:2024/05/17 03:19

题目链接:https://vijos.org/problems/P1253

描述

一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离d1、汽车油箱的容量c(以升为单位)、每升汽油能行驶的距离d2、出发点每升汽油价格p和沿途油站数n,油站i离出发点的距离d、每升汽油价格p。
计算结果四舍五入至小数点后两位。
如果无法到达目的地,则输出-1。

格式

输入格式

输入共n+1行,第一行为d1,c,d2,p,n,以下n行,每行两个数据,分别表示该油站距出发点的距离d和该油站每升汽油的价格p。两个数据之间用一个空格隔开。

输出格式

一行,输出最少费用。
计算结果四舍五入至小数点后两位。
如果无法到达目的地,则输出-1。


本题练习贪心算法。

分析:走到能走到之内的第一个价格比当前所在点便宜的加油站,如果之后能走到的所有站都比当前点贵 那么就加满油 走到能走到的最便宜的一个站。

 如果在这个范围内存在一个加油站j,它的价格pri[j]<pri[i],那么只要把油加到刚好能到达j就可以了;如果在这个范围内不存在这样的加油站,那么就在i加满油,然后走到最便宜的加油站j,如果无法走到j,即最近的加油站dis[j]>dis[i]+c*d2,此时无解。

代码:

#include <stdio.h>#include <stdlib.h>using namespace std;#define maxn 102double d[maxn];//距离double c;//容量double d2;//每升油能行驶的距离double p[maxn];//汽油价格int n;//加油站个数double cost;//花费double rest;//油箱油量剩余int main(){    /*#ifndef ONLINE_JUDGE        freopen("in.txt","r",stdin);    #endif*/    double d1;    scanf("%lf %lf %lf %lf %d",&d1,&c,&d2,&p[0],&n);    for(int i=1;i<=n;i++)    {        scanf("%lf %lf",&d[i],&p[i]);    }    d[n+1] = d1;    p[n+1] = 0;    d[0] = 0;    cost = 0;    rest = 0;    int k = 0;    while(k<=n)    {        int j = k;        int flag = 0;        int min = 0;        double need = 0;//在k处需要加多少油        while(d[j+1] - d[k] <= c * d2 && j<=n)        {            j++;            //最近的比当前加油站低的            if(flag == 0 && p[j]<p[k])            {                flag = j;            }            //最便宜的站            if(min == 0 || p[j]<p[min])            {                min = j;            }        }        if(k == j)        {            printf("-1\n");            return 0;        }        //没有比当前加油站价格低的,加满,走到最便宜的一个站        if(flag == 0)        {            need = c - rest;            cost += need * p[k];            rest = c - (d[min] - d[k])/d2;            k = min;        }        //最近的比当前加油站低的        else        {            need = (d[flag] - d[k])/d2 - rest;            if(need < 0)            {                need = 0;            }            cost += need * p[k];            rest = 0;            k = flag;        }    }    printf("%0.2lf\n",cost);    return 0;}


原创粉丝点击