【转】最快过桥问题

原文地址:  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;
    }
}
原文地址:https://www.cnblogs.com/cyttina/p/2742744.html