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

题意

你要从杭州开车到目的地,整条路线是一个数轴,你在数轴上的0点,目的地在距离0点为d米,你的车油罐的容量为C,每单位油可以行驶 D a v g D_{avg} Davg米,在路线上有n个加油站,每个加油站在位置为 d i d_i di的地方,且每个加油站的每单位油价为 p i p_i pi问你,从0点出发开到目的地所需要的最小花费是多少,若开不到目的地,输出最远可以到达的地方,油箱一开始为空

思路

贪心,读入后将加油站按距离排序,接下来用贪心的思想去求解。若排完序后第一个加油站所在的距离不为零,那么汽车肯定开不出去,特判一下这个情况,然后对于别的情况我们用贪心处理

  1. 我们把终点也加入到加油站的数组中,并且让其的油价为0
  2. 我们每次汽车肯定是开到莫一个加油站,然后在这个加油站考虑要去哪一个下一个加油站,以及在这个加油站中我们要加多少的油。
  3. 遍历在当前距离下,车辆加满油可以到达哪些加油站,若有加油站的价格比当前所在的加油站油价要便宜,我们只要加够能达到第一个比当前加油站便宜的加油站距离的油就可以了,若油箱里面剩下的油够直接达到那个加油站,就不需要加油,直接减去这段距离所花费的油就可以了
  4. 若没有加油站的油价比当前加油站的价格要便宜,那么我们给油箱从当前油量的基础上加满就可以了,然后选择一个可以达到的油价第二便宜的加油站,开到那里就可以了,若是除了终点之外没有可以达到的加油站,且终点还大于汽车的里程,那么输出当前所在的加油站的距离加上加满油能开的距离就是最后能达到的最远距离了
#include <bits/stdc++.h>
using namespace std;
struct node
{
    double d;
    double p;
} a[505];
bool cmp(node a,node b)
{
    return a.d<b.d;
}
int main()
{
    int c,d,p,n;
    scanf("%d%d%d%d",&c,&d,&p,&n);
    for(int i=0; i<n; i++)
        scanf("%lf%lf",&a[i].p,&a[i].d);
    a[n].d=d;
    a[n].p=0;
    sort(a,a+n+1,cmp);
    if(a[0].d!=0)
    {
        printf("The maximum travel distance = 0.00\n");
        return 0;
    }
    double ans=0;
    double dist=0;
    double now=0;
    int cnt=0;
    for(int i=0; i<n;)
    {
        int pos=i;
        double minn=a[i].p;
        for(int j=i+1; j<=n; j++)
        {
            if(a[j].d>dist+c*p)
                break;
            if(minn>=a[j].p)
            {
                pos=j;
                minn=a[j].p;
                break;
            }
        }
        if(pos==i)
        {
            ans+=(c-now)*a[i].p;
            now=c;
            pos=i+1;
            minn=a[pos].p;
            for(int j=pos+1; j<n; j++)
            {
                if(a[j].d>dist+now*p)
                    break;
                if(minn>=a[j].p)
                {
                    pos=j;
                    minn=a[j].p;
                    break;
                }
            }
            now-=(a[pos].d-dist)/p;
            if(now<0)
                break;
            dist=a[pos].d;
            i=pos;
        }
        else
        {
            double temp=(a[pos].d-dist)/p;
            if(temp>now)
            {
                ans+=(temp-now)*a[i].p;
                now=0;
            }
            else
            now-=temp;
            dist=a[pos].d;
            i=pos;
        }
    }
    if(dist==d)
    printf("%.2f\n",ans);
    else
    printf("The maximum travel distance = %.2f\n",dist+c*p);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值