首页 > 代码库 > 经典智力题:火车运煤

经典智力题:火车运煤

题目描述如下:

        你是一个煤老板,你在矿区开采了3000吨煤,需要运送到市场上去卖,从你的矿区到市场有1000公里,你手里有一列以煤为动力的火车,这个火车一次最多能运1000吨煤,火车每公里消耗一吨煤。问如何运送才能运最多的煤到集市?

========== -.- ==========









思考时间









========== -.- ==========

从题中很容易能看出一个矛盾:路程是1000公里,最多运1000吨煤,显然不能直接走。如果直接走的话,不仅没有煤能送过去,而且还会剩下一大堆煤在原地。所以肯定是要把原地的煤全都利用起来。所以需要设立中转站。那么问题就变成了需要几个中转站,各在什么位置?

先从简单入手,首先先在正中间位置,即500公里处设一个中转站,看看有没有什么效果。为了达到"运最多的煤到终点"的目的,肯定是不应该有煤留在原地的。所以一开始肯定是要把煤都拿出来,因为一共有3000吨煤,所以第一次搬1000吨出发,到了500公里处剩下500,但是为了能够回去,500吨煤必须全部带回去。所以第一趟白费力气,浪费了1000吨。第二个1000吨也是如此。运第三个1000吨的时候,由于不需要再回去,所以现在得情况是,火车有500吨煤,离终点500公里。所以这样的中转站没有任何用处,最后能运的煤是0。

但是上述的想法还是能有很多启发的。从题面可以看出,必须设立中转站,而从上述失败的运送办法中可以看出:设立中转站的目的是,我们得让所有煤不断地靠近终点。虽然来回跑更费煤,但是煤总量十分过剩,而运载量有限,所以要以"来回跑"的方式让煤不断接近终点。

我们还要明确一点:假如路上一共有N个中转站,我们首先要在起点和第一个中转站来回跑直到运空煤,然后在第一二个中转站之间来回跑,直到把煤运空。跨站运煤并不会更优,跨站是一样的或者更加浪费。那么一个完美的试探方案就出来了:既然不跨站,那就直接观察当前状态,如果火车与终点之间加上中转站会更优,那就加上去,否则直接走。

那么我们将中转站设在400公里处呢?第一趟来回消耗800吨,中转站留下200吨。第二趟来回消耗800,中转站留下200吨。第三趟直接过来,到达中转站还剩600吨。现在火车离终点600公里,且火车所属的中转站有1000吨煤。直接出发,最后成功运送400吨到终点站。

一开始由于距离足够远,显然是要来回跑让所有煤更靠近终点,当距离不太远时就得做出选择了:来回跑以搬运所有煤,还是一次性带上尽可能多的煤直接走。设距离为X公里。当前煤有R吨。

当R<=1000,显然是直接走。
当1000<R<=2000时,要走3趟(过去、回来、过去),很容易能写出公式:(1000-2x) + (R-1000)-x > 1000-x,解得X<(R-1000)/2时来回跑更优,否则带上1000吨直接走。
当2000<R<=3000时,要走5趟,解得当X<(R-1000)/4时来回跑,否则带上1000吨直接走。

当我们每隔250米设一个中转站时,最后能运送的煤是500吨。这是我当时以为的最优结果了。


当时脑袋没有转过来,过了好久才找到比500还要大的方案。靠直觉来猜测中转站的位置和数量,从而慢慢得到最优解显然不是什么好主意。我们知道来回跑太费煤,所以能不来回跑就不来回跑。初始化煤有3000吨,第一回合肯定是5趟来回,设运了X公里。X显然<500(参考上文的第一想法),所以第一回合结束后剩下的距离>=500米。所以如果有更优解,第二回合肯定不是直接走。那么至少还会有第二个中转站了。这个时候的思路非常关键,我们需要先判断一回合后的剩余煤量然后才能依次做出最优选择。

①假设一回合后剩余煤<=1000吨。那么第二回合直接走,方程如下:

        y = Max[3000-5x-(1000-x)] = 2000-4x

        因为3000-5x<=1000,所以x>=400,所以y<=400

②假设一回合后剩余煤量依旧>2000

        如果是这种情况,说明第一回合走的路相当短。我们知道,当结果>2000吨时,中间过程分一次还是多次是一样的。比如第一回合走了100公里,剩余煤2500吨,这和分别走两个50公里或4个25公里是相同的。若剩余2000吨以上火车还是要继续5趟5趟的搬运,所以我们直接把多段合并成一段,一样的。所以我们不考虑情况②

③假设一回合后剩余煤量在1000吨和2000吨之间

        通过情况2的分析,我们发现其实只会有①③两种情况。我们还发现,当R处于同一大段的时候,多次和一次的结果是相同的。所以情况③我们也是不断的运煤直到煤量剩余1000吨,然后直接走。

这样看来就是3回合了。

第一回合运了2000吨煤到中转站,消耗1000吨,因为5x=1000,所以第一回合走了200米。

第二回合运了1000吨煤到中转站,消耗1000吨煤,因为3x=1000,所以第二回合走了1000/3米。

第三回合带着1000吨煤直接走,经过前面的运送,还剩下1000-200-1000/3=1400/3公里,所以最终剩余1000-1400/3=1600/3≈533吨。

由于是边思考边写博客,思路可能有点乱 -.-