穿越沙漠的问题

一、问题描述


    一辆吉普车来到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.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值