设置大小为d(总距离)的flag数组,初始值为-1,表示每个地方都不可达 按照价格从低到高的顺序遍历每个加油站,对每个加油站,计算它加满油的情况下能覆盖哪些地方。例如,容量为Cmax,每单位汽油可以跑的距离为Davg,当前遍历到的加油站位置为Di,价格为Pi——则遍历flag数组,把所有flag数组上范围在[Di,Di+Cmax*Davg)内,且值为-1的位置设为Pi/Davg,表示这个位置可达,并且开完这一公里需要花费Pi/Davg。(注意:Pi要设置成double,float的精度不够)

最后从前往后遍历flag数组。如果遇到-1,则无法完成旅行,且第一个-1出现的位置就是能到达的最远距离;如果一直没有出现-1,只要把flag数组每个位置上的值加起来,就是最便宜的总花费了。

这道题而言这个贪心算法应该是最佳。

#include <iostream>
#include <algorithm>

using namespace std;

//习题7.2 To fill or not to fill

struct station{
    double price;
    int station_d;
};
int compare(station x,station y){
    return x.price<y.price;
}

int main(){
    int cmax,d,davg,n;//容量,距离,每单位汽油的距离,加油站数
    int i;
    while(scanf("%d%d%d%d",&cmax,&d,&davg,&n)!=EOF){
        double cost=0;
        double flag[d];
        for(i=0;i<d;i++)
            flag[i]=-1;
        station s[n];
        for(i=0;i<n;i++){
            scanf("%lf%d",&s[i].price,&s[i].station_d);
        }
        sort(s,s+n,compare);
        for(i=0;i<n;i++){//遍历所有加油站
            for(int plot=s[i].station_d;plot<s[i].station_d+cmax*davg && plot<d;plot++)//当前加油站所能覆盖的所有距离
                if (flag[plot]<0)flag[plot]=s[i].price;
        }
        for(i=0;i<d;i++){
            if (flag[i]<0){
                printf("The maximum travel distance = %.2f\n",float(i));
                break;
            }
            cost+=flag[i]/davg;
        }
        if(i==d){
            printf("%.2f\n",cost);
        }
    }
    return 0;
}