NOIP1999提高组 旅行家的预算

NOIP1999提高组 旅行家的预算

题目描述

    一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1、汽车油箱的容量C(以升为单位)、每升汽油能行驶的距离D2、出发点每升汽油价格P和沿途油站数N(N可以为零),油站i离出发点的距离Di、每升汽油价格Pi(i=1,2,…,N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

输入输出格式

    输入格式:

    第一行,D1,C,D2,P,N。
    接下来有N行。
    第i+1行,两个数字,油站i离出发点的距离Di和每升汽油价格Pi。

    输出格式:

    所需最小费用,计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

输入输出样例

    输入样例:

    275.6 11.9 27.4 2.8 2
    102.0 2.9
    220.0 2.2

    输出样例:

    26.95

说明

    N≤6,其余数字≤500

解题分析:

    采用贪心算法
    从某一点(假设为k加油站,开始为起点)出发,计算从该点出发加满油所能走到的最远距离。包括以下几种情况:
    1、所达到的距离内,有加油站的油价比加油站k的油价低(假设第一个为x加油站),则在k加油站加适量的油,开到x油站时正好油用完,并以x加油站为起点继续判断。此时邮箱没有余油。
    2、所达到的距离内,没有加油站的油价比加油站k的油价低(假设这些油站中x油站的油价最低),则在k加油站加满油,开到x加油站时以x为起点继续判断。此时邮箱有部分余油,在计算从x加油站所加的油量时要减去该余油数。如果此时能到达终点,则从x加油站加适量的油能够开到终点即可。
    3、如果在某个油站加满油不能跑到下一油站,则输出“No Solution”。

    在实现时,将起点和终点都加入到加油站数组,其中起点的距离为0,终点的距离为D1, 油价为一个较大值,比如1000

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main(){
	ios::sync_with_stdio(false);
	double d1, c, d2, p, p1, dis, ans = 0.0, min, rem;
	double sta[8][2];
	int n, i, start, flag, min_i;	
	cin>>d1>>c>>d2>>p>>n;
	sta[0][0] = 0;
	sta[0][1] = p; 
	for(i=1; i<=n; i++)
		cin>>sta[i][0]>>sta[i][1];
	sta[++n][0] = d1; 
	sta[n][1] = 1000;
	dis = c * d2;	// 从起点出发最多能走的距离 
	start = 1;		// 起点的油站编号 
	rem = 0;		// 到达该起点时,邮箱剩余油量 
	p1 = p;			// 起点油价 
	while(1){
		flag = 0;
		min = 1000;
		for(i=start; i<=n; i++){
			if(min > sta[i][1]){
				min = sta[i][1];
				min_i = i;								
			}				
			// 从出发点开始,能够到达比它油价低的加油点 
			if(sta[i][0] <= dis && sta[i][1] <= p1){ 
				ans += ((sta[i][0] - sta[start-1][0]) / d2 - rem) * sta[start-1][1];
				start = i+1;
				dis = sta[i][0] + c * d2; // 加满有所能跑的最长距离 
				p1 = sta[i][1];
				rem = 0;  // 到该油站时,正好将油用完
				flag = 1;
				break;
			}
			if(sta[i][0]>dis){  //没有油价比起点更低的加油站  
				flag = 2;				
				break;
			}			
		}
		if(flag == 2){
			ans += sta[start-1][1] * (c - rem); // 在上一个起点处,将邮箱加满
			// 从加油站min_i继续出发,注意此时邮箱有余油 
			rem = c - (sta[min_i][0] - sta[start-1][0]) / d2;
			start = min_i+1;
			dis = sta[min_i][0];			 
			p1 = sta[min_i][1];
			flag = 0; 
		}		
		else if(!flag){ // 已经走到终点或出现不能逾越的距离 
			if(i==start && sta[i][0] - sta[i-1][0] > c * d2){
				cout<<"No Solution"< c*d2){
				cout<<"No Solution"<

你可能感兴趣的:(NOIP,贪心)