旅行家的预算

旅行家的预算

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

Input

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

Output

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

Sample Input

275.6 11.9 27.4 2.8 2
102.0 2.9
220.0 2.2

Sample Output

26.95

Analysis

贪心策略:
1.从当前加油站出发,一个一个往后找(保证加满油能够开到),一旦遇到一个油价比当前加油站低的,就开过去,当然,有够就开过去,油不够就加到刚好够再开过去;
2.如果没有油价比当前低,就找出第二低的,加满油开过去;
3.当到不了下一个加油站时,输出-1;

Code

#include<cstdio>
#include<climits>
struct jyz{
    double d,p;
}a[105];
int n,nwi,i;
double D,C,D2,ans,yu;
int main()
{
    double sam;
    scanf("%lf%lf%lf%lf%d",&D,&C,&D2,&a[0].p,&n);
    for(i=1;i<=n;i++)
        scanf("%lf%lf",&a[i].d,&a[i].p);
    a[n+1].d=D;//将终点坐标赋给n+1
    while(a[nwi].d<D)
        {
            int id=-1;//判断是否找到以及存储坐标
            for(i=nwi+1;i<=n+1;i++)
            {
                if(a[i].d<C*D2+a[nwi].d)//在最大路程内往后找
                {
                    if(a[i].p<a[nwi].p) {id=i;break;}//找到就存坐标,后面好计算
                }
                else break;//如果不满足条件,再往后找也不会满足条件,退出
            }
            if(i==nwi+1&&id==-1) {printf("-1\n");return 0;}//如果到不了下一个站,输出-1
            if(id!=-1)//找到比当前小
            {
                if(a[nwi].d+yu*D2>=a[i].d)/*油够*/ yu-=(a[i].d-a[nwi].d)/D2;
                else/*不然加到刚好开过去*/{ans+=((a[i].d-a[nwi].d)/D2-yu)*a[nwi].p;yu=0;}
            }
            else//没找到比当前小
            {
                sam=INT_MAX;//存除当前加油站油价最少的  
                id=-1;//存坐标
                for(i=nwi+1;i<=n+1;i++)//终点油价为0,也要包含进去,这样才能到达终点
                {   
                    if(a[nwi].d+C*D2>=a[i].d)//距离够
                    {
                        if(sam>=a[i].p){ sam=a[i].p;id=i;}//储存
                    }
                    else break;  
                } 
                ans+=(C-yu)*a[nwi].p;  
                yu=C;//油要加满(这是最划算的)
                yu-=(a[id].d -a[nwi].d)/D2;  
            }  
            nwi=id;//更新坐标
        }
    printf("%.2lf\n",ans);
    return 0;
}

戳我,看更多博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值