hznu 1628: 旅行家的预算(贪心,分类)

91 篇文章 2 订阅
27 篇文章 0 订阅

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

输入

 第一行是五个数依次为:D1  C  D P  N

接下来有N行,每行包含两个数DiPi。

(其中只有N是正整数,其余均为正实数。C和N小于100,其余输入均小于1000。)

输出

最少费用。

样例输入

275.6 11.9 27.4 2.8 2
102.0 2.9
220.0 2.2

样例输出

26.95
http://hsacm.cn/JudgeOnline/problem.php?id=1628

更详细的题解:http://neik.blog.163.com/blog/static/747032102008614113125748/

#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<cmath>
#include<queue>
#include<stdlib.h>
#include<map>
#include<vector>
#include<cstdio>
#define ll long long
using namespace std;
struct node{
	double dis,cost;
}x[101];
int main(){  
	double d1,c,d2;
	int n;
	x[0].dis=0;
	cin>>d1>>c>>d2>>x[0].cost>>n;
	for(int i=1;i<=n;++i)
		cin>>x[i].dis>>x[i].cost;
	x[n+1].dis=d1;//将终点也看作一个加油站,并将终点站的油价赋为0
	x[n+1].cost=0;
	for(int i=1;i<=n+1;++i){
		if(x[i].dis-x[i-1].dis>c*d2){  //相邻加油站的距离>最大行驶距离
			cout<<"No Solution"<<endl;
			return 0;
		}
	}
	double sum=0; //总花费
	double w=0;  //目前油箱中油的体积
	int i=0,p;
	while(i<=n){
		for(int j=i+1;j<=n+1;++j){
			if(x[j].cost<x[i].cost){//找到下一个油价比当前站油价低的加油站p
				p=j;
				break;
			}
		}
		if(x[p].dis-x[i].dis>c*d2){//如果不能到达,在当前站加满油,行驶到下一个加油站
			sum+=(c-w)*x[i].cost;
			w=c-(x[i+1].dis-x[i].dis)/d2;
			i++;
		}
		else if(w*d2>=x[p].dis-x[i].dis){//如果用目前车上的油能到达p站,直接到p站
			w-=(x[p].dis-x[i].dis)/d2;
			i=p;
		}
		else{ //如果用目前车上的不油能到达p站,则在当前站加油使汽车刚好能到达p站
			sum+=((x[p].dis-x[i].dis)/d2-w)*x[i].cost;
			w=0;
			i=p;
		}
	}
	printf("%.2lf",sum);
    return 0;  
}  

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值