欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PAT1033 To Fill or Not to Fill

程序员文章站 2024-03-13 23:00:46
...

1033 To Fill or Not to Fill

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: CmaxC_{max}, the maximum capacity of the tank; D (≤30000), the distance between Hangzhou and the destination city; DavgD_{avg}, 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: PiP_{i} , the unit gas price, and DiD_{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

解题思路:
思路参考自https://www.jianshu.com/p/00905ef1d79e
主要考察贪心,注意到过程最优导致全局最优,就到第ii个站最优时,到第i+1i+1个站也是最优的。
贪心的具体策略:

  1. 从当前站寻找下一个第一次小于当前油费的车站。
  2. 如果没找到,看当前站+加满油后能不能到达终点,如果能,输出总费用,结束。
  3. 如果还不能到达终点站,从当前站加满油到下一个能到达的局部最小站,同时记录剩余的油量。

最后注意一个小case:
如果出发点不从0开始,那么最远达到的距离为0,因为在0处油箱是空的qwq

#include <iostream>
#include<cstdio> 
#include<algorithm>
#define MAX 0xffffff
using namespace std;
struct Station{
	int dis;
	double price;
}t[505];
bool cmp(Station &a,Station &b){
	return a.dis<b.dis;
}
int main(int argc, char** argv) {
	int Cmax,D,Davg,N;
	scanf("%d%d%d%d",&Cmax,&D,&Davg,&N);
	for(int i=0;i<N;i++){
		scanf("%lf %d",&t[i].price,&t[i].dis);
	}
	sort(t,t+N,cmp);
	if(t[0].dis!=0){//出发点不从0开始,这时候没有油,跑不动==.==
	  printf("The maximum travel distance = 0.00");
	  return 0;
	}
	
	double left=0,cos=0;
	int last=-1,flag2=0,cnt=0;
	for(int i=0;i<N;){
		int flag=0;
		for(int j=i+1;j<N&&t[i].dis+Cmax*Davg>=t[j].dis;j++){
			if(t[j].price<t[i].price){
				cos+=((t[j].dis-t[i].dis)/(Davg+0.0)-left)*t[i].price;
				left=0;//走到下一个station时剩余的油
				last=j;
				flag=1;
				break;
			}
		}
		if(!flag){//没找到
			if(t[i].dis+Cmax*Davg>=D){
				cos+=((D-t[i].dis)/(Davg+0.0)-left)*t[i].price;
				left=0,flag2=1;
				printf("%.2lf",cos);
				return 0;
			}else{
				double minPrice=MAX;
				int ind=i;
				for(int k=i+1;k<N&&t[i].dis+Cmax*Davg>=t[k].dis;k++){
					if(t[k].price<minPrice){
						minPrice=t[k].price;
						ind=k;
					}
				}
				cos+=(Cmax-left)*t[i].price;
				left=Cmax-(t[ind].dis-t[i].dis)/(Davg+0.0);
				last=ind;
			}
		}
		i=last;
		cnt++;
		if(cnt>=N) break;
	}
	if(!flag2){
		printf("The maximum travel distance = %.2lf",t[last].dis+Cmax*Davg+0.0);
	}
	return 0;
}
相关标签: 贪心