【转】最快过桥问题
原文地址: http://blog.csdn.net/wcyoot/article/details/6428248
貌似原文说的不是太详细,表示理解之后,在这里重新解释下,同时感谢原文博主提供了这么多题目以及解答。
题目:
4个人在晚上过一座小桥,过桥时必须要用到手电筒,只有一枚手电筒,每次最多只可以有两人通过, 4个人的过桥速度分别为1分钟、2分钟、5分钟、10分钟,试问最少需要多长时间4人才可以全部通过小桥?
抽象:
N个人过桥,每个人过桥需要的时间为ti(1<=i<=N).每次最多两个人过桥,并且还要回来一个。求最快过桥时间。
输入:每人过桥时间数组,人数(数组元素个数)。
输出:最快时间。
分析:
如果N<=2,则两个人一起过桥即可
如果N==3,则用最快的人送两个人过桥即可
如果N==4的情况。
假设 ABYZ 四个人的速度分别为 abyz,其中a最快,z最慢
则可以考虑以下两种过桥方案。
方案一:
A护送所有人过桥,也就是: AZ过桥(z) , A回来(a) , AY过桥(y) , A回来(a) , AB过桥(b),所用的时间为 2a+b+y+z
方案二:
AB过桥(b) , A回来(a) , ZY过桥(z) , B回来(b) , AB过桥(b) , 所用的时间为: a+2b+z
这样,如果方案一的时间小于方案二的时间,即 a+y < 2b ,则采用方案一
如果方案二的时间小于方案一,则采用方案二。
如果 N > 4 的时候,分析完成的结果依旧和 N == 4 的情况一致,所以N>=4 就是剩下的情况。
根据以上的描述,就可以采用一个递归的形式搞定这个问题。
代码如下:
int TravelBridge(std::vector<int> times) { int length = times.size(); if(length <= 2) return times[length-1]; else if(length == 3) return times[0]+times[1]+times[2]; else { int totaltime = 0; int a = times[0]; int b = times[1]; int z = times[length-1]; int y = times[length-2]; if(b*2 < a + y) { times.erase(times.end()-1); times.erase(times.end()-1); totaltime += b + a + z + b + TravelBridge(times); } else { times.erase(times.end()-1); totaltime += z + a + TravelBridge(times); } return totoaltime; } }