一、问题描述
一辆吉普车来到1000km宽的沙漠边沿。吉普车的耗油量为1L/km,总装油量为500L。显然,吉普车必须用自身油箱中的油在沙漠中设几个临时 加油点,否则是通不过沙漠的。假设在沙漠边沿有充足的汽油可供使用,那么吉普车应在哪些地方、建多大的临的加油点,才能以最少的油耗穿过这块沙漠?
二、问题分析
为了能以最少的油耗穿过沙漠,所以汽车每次必须满载(500L),以尽量减少搬油的次数。每个加油站的油量也应该是500L的整数倍。考虑最后一个加油站,由于汽车最多能装500L油,而要使我们最后的耗油量最少就不能有浪费,所以这个加油站的油量应该为500L,而它的距离应该为到终点处500km,我们为这个加油站编号为A1。为了给A1加油站运送500L油。汽车至少要访问A1两次(因为汽车最大能装500L,而且它还要烧油)。所以下一个加油站A2距离A1为500/3 km(汽车第一次从A2到达A1后要返回,第二次不用返回,每次返回后都不剩油,而且每次出发前都是满载)。经过上面分析,A2的储油量应该为1000L。同理,A3的储油量为1000+500=1500L,与A2的距离为500/(2*2+1)km……
通过上面的分析发现,每两个加油站之间的储油量之差为500L。
每个加油站Ai距离上一个加油站为:500/(2*i-1)。
例如:
A1:
500/(2*1 - 1) = 500
A2:
500/(2*2 - 1) = 500/3
A3:
500/(2*3 - 1) = 100
A4:
500/(2*4 - 1) = 500/7
...
Ai:
500/(2*i - 1)
现在的目标是:
Sum(A1..Ai) > 1000
即:
500*(1 + 1/3 + 1/5 + ... + 1/(2*i-1)) > 1000
解出这个不等式就是本题最终的结果。
三、程序代码
1 int gas_station(double distance,double cost_per_km, double gas_cnt)
2 {
3 double sum;
4 int i, j;
5 double total_gas, station_pos;
6 double step;
7
8 sum = 0.0;
9 i = 1;
10
11 //calculate the number of stations
12 while (sum <1.0)
13 {
14 sum += 1.0/(2*i + 1);
15 i++;
16 }
17
18 station_pos = 0.0;
19 total_gas = gas_cnt * i;
20 step = gas_cnt / cost_per_km;
21
22 for (j =1; j <= i; j++)
23 {
24 distance -= step/(2*j -1);
25 printf("NO.%d station, dist =%f, gas = %f.\n", i-j+1, distance, gas_cnt * j);
26 }
27 return 0;
28 }
29
30 int main()
31 {
32 gas_station(1000,1, 500);
33 return 0;
34 }
运行结果:
NO.8 station, dist = 500.000000, gas = 500.000000.
NO.7 station, dist = 333.333333, gas = 1000.000000.
NO.6 station, dist = 233.333333, gas = 1500.000000.
NO.5 station, dist = 161.904762, gas = 2000.000000.
NO.4 station, dist = 106.349206, gas = 2500.000000.
NO.3 station, dist = 60.894661, gas = 3000.000000.
NO.2 station, dist = 22.433122, gas = 3500.000000.
NO.1 station, dist = -10.900211, gas = 4000.000000.