1033 To Fill or Not to Fill @PTA

With highways available, driving a car from Hangzhou to any other city is easy. But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time. Different gas station may give different price. You are asked to carefully design the cheapest route to go.

Input Specification:

Each input file contains one test case. For each case, the first line contains 4 positive numbers: C​max​​ (≤ 100), the maximum capacity of the tank; D (≤30000), the distance between Hangzhou and the destination city; D​avg​​ (≤20), the average distance per unit gas that the car can run; and N (≤ 500), the total number of gas stations. Then N lines follow, each contains a pair of non-negative numbers: P​i​​, the unit gas price, and D​i​​ (≤D), the distance between this station and Hangzhou, for i=1,⋯,N. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the cheapest price in a line, accurate up to 2 decimal places. It is assumed that the tank is empty at the beginning. If it is impossible to reach the destination, print The maximum travel distance = X where X is the maximum possible distance the car can run, accurate up to 2 decimal places.

Sample Input 1:

50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
7.30 1000
6.85 300

Sample Output 1:

749.17

Sample Input 2:

50 1300 12 2
7.10 0
7.00 600

Sample Output 2:

The maximum travel distance = 1200.00

很好的贪心题目。

分情况做对策:

设在一个车站加满油后能跑出的最大距离为max_dis

同时可以把终点看作一个车站,价格设为0,方便处理。

一、 max_dis范围内没有车站,也没有到达终点,GG,输出该车站的距离+max_dis;

二、范围内有车站:

1.某一车站价格比当前车站小,那么加够恰好到达该车站的油开往该车站。

2.范围内所有车站价格都比当前车站大,加满油箱,直接开往能够到达的最远的车站,因为当前车站加的油是最省钱的。注意,这种情况下到达最远车站时油箱里的油可能还有剩余,也就是说从每个车站出发时还要考虑到油箱是否还有油。

3.到达终点站。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#include <stack>
#include <iomanip>
#include <cstdlib>
#include <queue>
#define MAXN 100003

using namespace std;

struct Node{
	double p;
	double di;
}sta[503];

bool cmp(const Node &a,const Node &b){
	return a.di < b.di;
}

int main(){
	double c,d,da;
    int n;
	scanf("%lf%lf%lf%d",&c,&d,&da,&n);
 	for(int i=0;i<n;++i){
		scanf("%lf%lf",&sta[i].p,&sta[i].di);
	}
	sort(sta,sta+n,cmp);
    sta[n].p = 0;
    sta[n].di = d; //设置目的地为一个车站,价格为0
	double max_dis = da*c; //油箱加满时能够抛出的最远距离
	int cur = 0; //车子刚从哪个车站驶出或正位于哪个车站
	double dis = 0.0; //车子已经开出的距离,如果dis=某个车站的距离,说明车子正位于该车站;否则,说明车子刚从前面某个车站驶出,这样就可以表示利用油箱中剩余油能够跑到的最远距离
	double cost = 0.0; //车子开到当前距离的最小花费
    if(sta[0].di != 0.0){ //特殊情况,起点没有车站时,车子开不出来
        printf("The maximum travel distance = 0.00\n");
        return 0;
    }
    while(true){
        if(cur == n){ //车子到达终点
            printf("%.2lf\n",cost);
            return 0;
        }
        int pos = -1;//当前方车站价格都大于当前车站时,记录能够到达的最远的车站
        for(int i=cur+1;i<=n;++i){
            if(sta[cur].di + max_dis >= sta[i].di){
                if(sta[i].p < sta[cur].p){ //当某一车站价格更小时
                    cost += sta[cur].p * (sta[i].di - dis)/da;
                    dis = sta[i].di;
                    cur = i;
                    break;
                }
                else{
                    pos = i;
                }
            }
            else {
                if(pos == -1){ //说明前方max_dis范围内没有车站
                    printf("The maximum travel distance = %.2lf\n",sta[cur].di + max_dis);
                    return 0;
                }
                else{ //否则,满油开到能到达的最远的车站,注意,车子不一定就停靠在该车站,也有可能驶过该车站,但要在经过该车站时维护状态。
                    double tmp = dis;
                    dis = sta[cur].di + max_dis;
                    cost += sta[cur].p * (dis-tmp)/da;
                    cur = pos;
                    break;
                }
            }
        }
    }
    // printf("%.2lf\n",cost += sta[cur].p*(d-dis)/da);
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值