汽车加油问题

问题描述:

一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,在哪些加油站停靠加油,使沿途加油次数最少。

对于给定的n(n <= 5000)和k(k <= 1000)个加油站位置,编程计算最少加油次数。

test.txt

7 7

1 2 3 4 5 1 6 6

 

output.txt

4

算法思路:

首先加油站之间的距离d必须小于汽车加满油行使的公里数,即d<n。该问题需要使得加油次数最少,所以只要行使到编号为i加油站后,剩余的油能够成功行使到编号为i+1的加油站,那么就不需要在编号为i的加油站加油。只有剩余的油量不足以行使到编号为i+1的加油站,才需要在编号为i的加油站加油,否则将无法成功到达目的地。为了计算加油次数,引入numbers变量计数;为了输出加油站的编号,引入x[k+1]数组标记加油站的编号。x[i]=0,表示未在编号i的加油站加油; x[i]=1,表示在编号为i的加油站加油。

 该算法的贪心选择的意义是,使每一次加油尽可能行使到最远的距离,以此来减少加油的次数。

代码:

#include <iostream>
#include <stdio.h>
using namespace std;

void CarRefuelingGreedy(int n, int *d, int k,int *x,int &numbers){
	int i,sumD = n;         //sumD表示上一站剩余的油量
	numbers = 0;
	for(i = 1; i<=(k-1); i++){
		x[i] = 0;
	}
	for(i = 1; i<=k; i++){
		if(sumD<d[i]){      //上一站剩余的油量 小于 上一站到这一站需要的油量 
			x[i-1] = 1;		//在上一站加油 
			numbers++;		//加油次数加一 
			sumD = n-d[i];	//到这一站剩余的油量 
		} else{
			sumD-=d[i];
		}
	}
}

int main(){
	int n,k,numbers;
	FILE *f = fopen("test.txt","r");
	fscanf(f,"%d",&n);
	fscanf(f,"%d",&k);
	cout<<"加满油行驶的公里数:"<<n<<endl;
	cout<<"加油站数:"<<k<<endl;
	int *d = new int [k+2]; 
	int *x = new int [k+1];
	for(int i = 1; i<=(k+1); i++){
		fscanf(f,"%d",d+i);
		cout<<"加油站"<<i-1<<"加油站"<<i<<"之间的距离为:"<<d[i]<<endl; 
	} 
	CarRefuelingGreedy(n,d,k+1,x,numbers);
	cout<<"加油次数:"<<numbers<<endl<<"加油点:";
	for(int i = 1; i<=k; ++i){
		if(x[i]) cout<<"加油站"<<i<<" ";
	}
}

运行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值