火车运煤问题

网上有一道火车运煤的问题。

题目:

你是山西的一个煤老板,你在矿区开采了有3000吨煤需要运送到市场上去卖,从你的矿区到市场有1000公里,你手里有一列烧煤的火车,这个火车最多只能装1000吨煤,且其能耗比较大——每一公里需要耗一吨煤。请问,作为一个懂编程的煤老板的你,你会怎么运送才能运最多的煤到集市?

 

开始看到题目觉得没有解,火车运1000吨,到终点后,什么也没有了,都在路上消耗光了,但是一次性从头开到尾,还有很多煤在起点,没有运。因此火车不能一次性开到尾,一定先开到中途某一点,选择这一点作为中转站,卸下部分煤,然后返回再去运(当然前提条件是火车首尾都必须有火车头!)。既然是求最值问题,我首先想到的这道题可能的几个思路:1.建立数学方程求最值;2.通过编程穷举。

 

首先我自己想举个实际的情况看看,怎样运煤到终点。

假设火车开始行到400公里,然后卸煤。火车运送三次到400公里点处,在400公里处剩余1000吨(3000-5*400),剩下600公里,火车装满煤,然后到终点还剩400吨煤。

这说明火车是可以运煤到终点的。如何才能求的运送的最大值?我现在遇到的困难是:

1.火车可以现在任意个地方做为中转站。火车可以走到一公里处选择卸煤,剩下的煤刚够返回;火车还可以在100公里处选择卸煤,然后返回;甚至可以在10.4公里处,选择卸煤。

2.选择中转站的次数是任意的。比如从开始到100公里之间,我可以选择只在100公里处卸煤,再返回运煤;我也可以选择在中间某个地方卸煤,然后到100公里出卸煤;或者我可以选择中间两个地方作为中转站。可以选择中转站的次数是任意的。

3.选择同一个地方为中转站,但火车返回的趟数不固定。比如我一开始可以选择在100公里处选择卸煤,我可以返回一趟运煤;我也可以返回两趟运煤。

 这么看来可能运煤的方式有无数种,无从下手。


我就从一公里下手,假设火车每走一公里就选择中转站,然后回上次的出发点运煤,分析中会发现:

火车从A点出发,到B点中转,那么运煤的情况只可能是下面三种:

1. A运到B,不选择返回

2. A运到B,返回A一次,然后再回到B

3. A运到B,返回A两次,在返回B

这是因为:

火车最多运送1000吨煤,而煤的总量是3000吨,所以只能出现上面这三种情况。这是一个很重要的信息。

注意:为了尽可能多的运煤,每次从中转站返回时,火车装的煤刚好够返回,多余的煤存放在中转站。

我们又发现几个规律。

1.等效性。

假设从位置A运煤到位置B,返回A两次;从位置B运煤到位置C,返回B两次。这种运煤方式等效于:从A运煤到C,返回A两次。

 

2. 还可以发现一个规律,姑且叫返回次数不可增大性。

假设从位置A运煤到位置B,返回A一次;接着从位置B运煤到位置C,则到达C之后,最多只能返回一次B,然后再回到C。

原因:从A到B,返回A一次,所以火车从A运了两次煤到B,每次最多1000,火车行走还有消耗煤,所以火车运到B的煤总量必然小于2000。如果火车到达车C返回B两次,那么从A运到B的煤就必须大于2000,所以最多只能返回一次B,然后回到C。

每次从一个地方A运煤到另一个地方B,都要尽可能多的把A原有的煤运到B处。从出发点,我们就要把原先3000吨煤尽可能多的运到第一个中转站,开始一定是返回出发点两次(也就是运三次煤到第一个中转站);接着一定是返回一次到中转站(也就是运两次煤到第二个中转站);然后直接运煤到终点

所以,有上面的分析,即使可能会出现无数种运煤方式,最优的运煤方式一定符合下面的情行:

Start------------Two-------------One----------End

Start代表出发点;End代表终点;Two代表一个中转站,返回Start处两次(也就是从Start处总共运了三次煤到Two处);One代表一个中转站,返回Two处一次(也就是从Two出总共运了两次煤到One处);最后从One处直接运送一次煤到终点。

其它可能的情况:Start------------Two-------------End,这种情况也被上面所包含。当位置Two和位置One重合时就是这种特殊情况。

所以现在我们就对下面的情况进行分析。

Start------------Two-------------One----------End

假设Start处坐标为0,位置Two的坐标为X,位置One的坐标为Y。即:

0--------------X--------------------Y--------------1000

分两种情况讨论

I.3000-5X >= 2000, X<=200

这时运到Y处的煤总量是:2000-3(Y-X),再考虑两种情况,

 i)2000-3(Y-X) >= 1000, (Y-X)<=1000/3;

   最终运送到终点的煤:1000-(1000-Y)=Y

   Y<=1000/3+X=533.33

   所以最多是运送533.33,X=200,Y=333.33。

 ii)2000-3(Y-X) < 1000, 3(Y-X)>1000

   最终运送到终点的煤:

2000-3(Y-X)-(1000-Y)=1000-2Y+3X=1000-2(Y-X)+X<1000-1000*(3/2)+200=533.33

II.3000-5X < 2000, X>200

这时运送到Y处的煤总量是:3000-5X-3(Y-X)=3000-3Y-2X,同样再考虑两种情况,

i) 3000-3Y-2X>=1000

  最终运送到终点的煤:1000-(1000-Y)= Y,

  Y<=(2000-2X)/3<1600/3=533.33

ii) 3000-3Y-2X<1000

  最终运送到终点的煤:3000-3Y-2X-(1000-Y)= 2000-2Y-2X

由3000-3Y-2X<1000,得到2(Y+X)>(2000+X)*(2/3),

所以,2000-2Y-2X <2000 - (2000+X)*(2/3) <2000-(2000+200)*(2/3)=533.33

 

所以由上面分析知道最多运煤533.33吨。

你可能感兴趣的:(编程,c)