邮箱问题的诸多解法

来源:互联网 发布:c4droid图形编程 编辑:程序博客网 时间:2024/04/28 00:07

题目:
假设有一辆车,它的油箱恰好和一个油桶一样大,而且车上恰好可以装载一个桶。假设一桶油可以让车开100公里。现在在

起点,车装满了油,另外起点还有100桶油。问:这车最远能离开起点多远?  
说明:
汽车上最多带一个桶,不管这个桶里装了多少油,不能再带另外的空桶。桶中的油可以倒入油箱中,油箱中的油也可以倒入

桶中。 


 

解法一:
是最先想到的。很简单。加满油,再装一满桶油,这样就能跑100+100=200公里。
哇~真简单!

事实上,车可以走到半路,放下桶再回去装油。恩,以下都是按照这个思路设计的。


解法二:倒推。
将终点定为A0,终点的前一个点为A1,依次类推,A2,A3,...,起点为An。A1到A0间的距离为F1,   依次类推,F2,F3...

,Fn。
  A0----A1----A2----A3...----An
     F1    F2    F3   ... Fn     
1、很明显,当车到A2时,车上油箱为空,A2处有2桶油,F1为100,F2为100;  
2、A2处的2桶油,必须由A3处运到。  
   运送时必须走过的路程为A3->A2->A3->A2,即3*F3。  
   这个过程中共有两次是由A3出发,每次出发时油箱里加满油,又带一桶油,总共可以带4桶油(A3处要有四桶油),A2处

留下两桶,剩下的2桶油跑了3*F3的路程,可计算出F3=200/3=66.7;  
3、同样,可以计算出
A4处有8桶油,F4=400/7 =57.14;  
A5处有16桶,F5=800/15 =53.33;  
A6处有32桶,F6=1600/31=51.61;  
A7处有64桶,F7=3200/63=50.79;  
4、起点(A8)有101桶,将64桶油由A8运至A7,F8=(101-64)*100/(2*64-1)=29.13  
F1+...+F8   =   508.7

 

解法三:
  1、搬到最后结果应该是车没油,地上剩两桶油,能跑出200公里。  
  2、车里的油也算一桶,当油桶数是奇数的时候,花一桶油代价把另一桶油搬到50公里处是不划算的,例如剩3桶油,一桶

加满油箱,带上一桶开到50公里处放下,回来,剩下的一桶正好加满油箱,这时车在起点,总油量是2桶,结果3桶油只能跑

200公里。因此当油桶是奇数的时候,应该花一桶油的代价把剩下的油桶往前搬,设剩下的油桶数为n,搬的距离为x,则x*

(2n-1)=100,x   =   100/(2n-1),只所以减1是因为搬最后一桶油不需要返回了。3桶油耗一桶把剩下两桶搬到100/(2*2-

1)=33.3公里处,能跑出233.3公里。  
  3、油桶数是偶数,应该耗一桶油把另一桶油搬到50公里处,把所有油桶搬到位,车里是还剩50公里的油量的,因为不需

要返回。  
  4、按3的规则,例如剩6桶油,搬出50公里是剩3.5桶油,这个.5也算一桶油,因此油桶数还是偶数,仍然按3的规则搬,

不过搬到位车里已经没油了。6->3.5->2  
   
  按以上规则:  
  公里数:100/199=0.5       50           50/99=0.5     50  
  油桶数:101       100     50.5       50              25.5  
   
  剩25.5桶油的时候有个分歧,是花1.5桶油的代价把24桶油往前搬还是把13桶油搬出50公里,分别算一下:  
  1.5桶油搬24桶:  
  公里数:         |150/47=3.19|     50     |50/23=2.17|     50   |50/11=4.54|     50   |   50   |   200  
  油桶数:25.5     |     24      |    12.5   |    12 |   6.5   |    6    |   3.5   |   2   |  
   
  搬出50公里:  
  公里数:         |    50     |    100/23=4.34|50   |     50/11=4.54|50   |   50   |   200  
  油桶数:25.5     |    13     |    12   |    6.5    |    6    |    3.5    |    2  
   
  最后最大值是:0.5+50+0.5+50+3.19+50+2.17+50+4.54+50+50+200   =   510.9公里  

 

解法四:
配对跑------,两桶一组,前进50公里,卸下一桶油,再退回,最后不需要退时就不退了(省下半桶油),当然最后一组可以

是一桶半出发,抵达目的地时恰好剩一桶。这是最又效率的一种跑法。推进路程m=x(桶)*100/(n(待推进桶数)-1);  
   
蛇形跑------用一桶或半桶油尽其所能做蛇形往返跑,折返点要计算好,使得所有其他油桶恰好可以被摆渡到前方的折返点

,例如现有5桶油,用其中一桶做燃料,做一个4去3回的蛇形折返跑,即可恰好将其他4桶油搬运至前方100/7=14.28公里处

。公式为:x为消耗的桶数,n为剩余要传递的桶数(包括油箱的油),推进路程m=x/(2n-1);  
   
桶数(n)------到达每一个前进营地时有油的桶的数目,半桶油算桶数是也算   1  
   
  原则方案:  
  桶数为奇数时,用其中一桶或半桶做燃料进行蛇形跑,烧每桶油可推进   100/(2n-1)公里.  
  桶数为偶数时,进行配对跑。  
  尽量使其做高效配对跑,看如下跑法就明白了,就是偏离后马上恢复。  
   
  剩余桶数         消耗桶数         推进路程               备注  
  101                   1          100/199=0.5025      蛇行跑  
  100                 49.5                50                    配对跑  
  50.5                  0.5          50/99=0.5050       蛇行跑  
  50                   24.5                50                    配对跑  
  25.5                  0.5                50                    蛇行跑  
  25                    12                  50                    配对跑  
  13                     6                  50                     配对跑  
  7                       3                  50                     配对跑  
  4                       1.5                50                    配对跑  
  2.5                    0.5                50/1                 蛇行跑  
  2                       2                 200                    痛快跑  
   
  总共推进路程:552.0279公里  
争议:
  算法中:  
  25.5                       0.5                     50                             蛇行跑  
  0.5桶油怎么把25桶油搬出50公里?是50/49   =   1.02公里  
  所以得出的总公里数552.0279得-50+1.02=502.0479。

 

解法四:
  配对跑------,两桶一组,前进50公里,卸下一桶油,再退回,最后不需要退时就不退了(省下半桶油),当然最后一组可

以是一桶半出发,抵达目的地时恰好剩一桶。这是最又效率的一种跑法。推进路程m=x(桶)*100/(n(待推进桶数)-1);  
   
  蛇形跑------用一桶或半桶油尽其所能做蛇形往返跑,折返点要计算好,使得所有其他油桶恰好可以被摆渡到前方的折返

点,例如现有5桶油,用其中一桶做燃料,做一个4去3回的蛇形折返跑,即可恰好将其他4桶油搬运至前方100/7=14.28公里

处。公式为:x为消耗的桶数,n为剩余要传递的桶数(包括油箱的油),推进路程m=x/(2n-1);  
   
  那么遵循以下方法可以获得512.146公里:  
  1.如果所余油桶数为2N+1,则用1桶进行蛇行跑;  
  2.如果所余油桶数为2N,则进行配对跑;  
  3.如果所余油桶数为2N+1.5,则用1.5桶进行蛇行跑;  
  4.如果所余油桶数为2N+0.5,则用0.5桶进行蛇行跑。  
   
  这说明配对跑是最有效率的,应该尽量用配对跑来跑。

 

解法五:
卡车与油问题还有油水!  
   
以前的解法都是所有油桶齐步走的,是否会有更好的步调?
现在先来看一个极简单的情况:5桶油  
   
照齐步走的推进法,最佳安排是   5...4---2.5...2,   成绩为100/7+50+50/3+200=280.952   公里。
   
现在找了一下,有一个“异步”的推进方案效果更好。
  从起点0公里处开始,先烧掉1号桶的油,做两进两退的运动,把2,3号油桶运到25.000公里处存放  
  现在车又在起点,烧4号桶的油,把5号桶前运到   62.500公里处,4号桶余油恰好够回到25.000公里处  
  现在从25.000公里处出发,烧2号桶的油,把3号桶运抵   83.333公里处   (即前进58.333公里),余油恰好够返回  

62.500   公里处并将早先放在那里的5号桶也运至83.333公里处  
  最后,再连续跑200公里,总成绩   283.333公里  
  结果,异步效率高于同步。  


 

其他理论解法:
·不用车来搬油,司机来搬。101*100=10100公里。
·不用油,推车走。想多远就多远。

担忧:
·油放在路上被偷了怎么办。

经典算法:
·谭浩强写的Basic程序设计一书有此题目。

原创粉丝点击