51Nod-1288-汽油补给

42 篇文章 0 订阅


题目来源:  Codility
基准时间限制:1 秒 空间限制:131072 KB 分值: 160  难度:6级算法题
 收藏
 关注
有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的汽油,油箱的容量是T。给出每个城市到下一个城市的距离D,以及当地的油价P,求走完整个旅途最少的花费。如果无法从起点到达终点输出-1。
例如D = {10, 9, 8}, P = {2, 1, 3},T = 15,最小花费为41,在0加上10个单位的汽油,在1加满15个单位的汽油,在2加2个单位的汽油,走到终点时恰好用完所有汽油,花费为10 * 2 + 15 * 1 + 2 * 3 = 41。
Input
第1行:2个数N, T中间用空格分隔,N + 1为城市的数量,T为油箱的容量(2 <= N <= 100000, 1 <= T <= 10^9)。
第2至N + 1行:每行2个数D[i], P[i],中间用空格分隔,分别表示到下一个城市的距离和当地的油价(1 <= D[i], P[i] <= 1000000)。
Output
输出走完整个旅程的最小花费,如果无法从起点到达终点输出-1。
Input示例
3 15
10 2
9 1
8 3
Output示例
41

51Nod1288 汽油补给

思路:

1.在当前城市p 在油满的条件下往前寻找首个比城市q的油价低的城市q

(只要找到一个油价低于p的城市q,则可以在q加油,从而费用最小)

2.对城市p,q的油价比较:若 q<=p,则加 dpq 的油量,否则加满油

3.汽车行驶到城市q,重复1—3步骤直到到达终点

* 加油过程需考虑以下情况:1.油箱内是否还有油。2.判断在加满油的情况下到达终点是否会剩下油

** 编程中需注意 爆数据类型


#include<iostream>
using namespace std;

typedef long long LL;
const int MAX_N=100005;
int n,T;
LL ans;
int D[MAX_N],P[MAX_N];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	LL surplus=0;	//long long
	cin>>n>>T;
	for(int i=0;i<n;++i)
		cin>>D[i]>>P[i];
	int sum,d,w;
	for(int k=0;k<n;k=d)
	{
		sum=D[k];
		d=k+1;	w=1e8;
		for(int i=k+1;i<n&&sum<=T;sum+=D[i++])
			if(w>=P[i]){
				d=i;	w=P[i];
				//找到一个油价低的城市则停止寻找 
				if(w<=P[k])	break;
			}
		if(D[k]>T){
			ans=-1;	break;
		}
		int dis=0;
		for(int i=k;i<d;++i)
			dis+=D[i];
		if(P[k]>=w){	//加 恰好到达城市p的油 
			ans+=P[k]*(dis-surplus);
			surplus=0;
		}else{	//加满油 
			if(sum>T){	//不能到达终点 
				ans+=P[k]*(T-surplus);
				surplus=T-dis;
			}else{	// 可到达终点
				ans+=P[k]*(sum-surplus);
				break;
			}
		}
	}
	cout<<ans<<endl;
	
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值