1033 To Fill or Not to Fill (25 分) 贪心算法

首先讲一下思路。
这道题是一个贪心算法的题,大体方法就是0.寻找比自己距离远的,到能够到达的最大距离之间的加油站,看他们的油价。如果找到了更低价格的油价,就加油到刚好能到达那个加油站的距离的油,然后去那个更低价格的加油站。如果找不到更低的,就找尽可能低的油价的加油站,在当前加油站加满油之后过去。因为想要让路程上使用的尽可能是低价的油,既然没有比当前更低价格的了,就让油箱加到最大值,这样能保证利益最大化,保证最大的距离使用的是便宜的油。
但有几个要注意的地方。
第一个是终点的处理。基本所有的解答都是将终点当作一个价格为0的车站和距离为最大距离的车站。其实自己写一遍这个题就知道,如果不将终点当做一个车站处理的话,解题将会非常麻烦。因为你需要在判断当前车站能不能直接到终点?不能到的话下一个车站能不能到?都不能的话是不是不存在最终答案?总之很麻烦。
第二个是油箱的问题。第一遍自己写到最后的时候就发现必须要加油箱这个参数,因为如果不加邮箱就会有一个致命的问题:如果在车程内不存在比当钱油价更便宜的车站,那么我的油就要加满,但是我在下一个车站要加多少油呢?因为如果下一个车站就可以到终点了,那么油就只用加刚刚好,如果下一个车站不能到终点,但存在更便宜的车站,那么加的油就还应该是到便宜车站距离的油。
如果想不明白就拿个纸和笔自己写一下,贪心的逻辑还是比较简单的。

还有一个题目默认的点,不存在两个距离一样的车站。

#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;

struct station
{
    double price,dis;
}st[500];

bool cmp1(station a,station b)
{
    return a.dis<b.dis;
}


int main()
{
    cout<<fixed<<setprecision(2);
    double cmax,d,davg;
    int n;
    cin>>cmax>>d>>davg>>n;
    for(int i=0;i<n;i++)
    {
        cin>>st[i].price>>st[i].dis;
    }
    st[n].price=0;
    st[n].dis=d;
    double dmax=cmax*davg;
    sort(st,st+n,cmp1);
    if(st[0].dis!=0)
        cout<<"The maximum travel distance = 0.00";
    else
    {
        double ans=0,nowtank=0;
        int now=0;
        while(now!=n) //直到终点站
        {//如果车程内存在价格更小的车站,直接去,否则下一个车站是价格最小的车站
            double minprice=999999999; //选出下一个价格最小的车站
            int k=-1; //下一个车站为k号站
            for(int j=now+1;j<=n;j++)
            {//遍历之后所有在车程范围内车站,如果存在一个更便宜的车站,
            //那么加到那个车站距离的油,到下一个车站油箱为0。否则,加满油
            //到一个车站时会有剩的站
                if(st[j].dis-st[now].dis>dmax) //不存在下一个可以到达的车站了
                    break;
                else
                {
                    if(st[j].price<minprice)
                    {
                         minprice=st[j].price;
                         k=j;
                    }
                    if(st[j].price<st[now].price)
                    {
                        break;
                    }
                }
            }
            if(k==-1)
                break;
            double need=(st[k].dis-st[now].dis)/davg; //这次行程需要的油
            if(minprice<st[now].price)  //距离内有更便宜的车站
            {
                if(nowtank<need) //油箱的油是不够的
                {
                    ans+=(need-nowtank)*st[now].price;
                    nowtank=0;
                }
                else  //油是够的
                    nowtank-=need;
            }
            else  //不存在这样一个车站
            {
                ans+=(cmax-nowtank)*st[now].price;
                nowtank=cmax-need;
            }
            now=k;
        }
        if(now==n)
            cout<<ans;
        else
           cout<<"The maximum travel distance = "<<st[now].dis+dmax;
    }

    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值