最快過橋問題

題目:

4個人在晚上過一座小橋,過橋時必須要用到手電筒,只有一枚手電筒,每次最多只可以有兩人通過, 4個人的過橋速度分別爲1分鐘、2分鐘、5分鐘、10分鐘,試問最少需要多長時間4人纔可以全部通過小橋?

 

抽象:

N個人過橋,每個人過橋需要的時間爲ti(1<=i<=N).每次最多兩個人過橋,並且還要回來一個。求最快過橋時間。

 

輸入:每人過橋時間數組,人數(數組元素個數)。

輸出:最快時間。

 

解析:

 

最佳方案構造:以下是構造N個人(N≥1)過橋最佳方案的方法:  
1) 如果N=1、2,所有人直接過橋。  
2) 如果N=3,由最快的人往返一次把其他兩人送過河。  
3) 如果N≥4,設A、B爲走得最快和次快的旅行者,過橋所需時間分別爲a、b;
 而Z、Y爲走得最慢和次慢的旅行者,過橋所需時間分別爲z、y。那麼    
 當2b>a+y時,使用模式一將Z和Y移動過橋;    
 當2b<a+y時,使用模式二將Z和Y移動過橋;    
 當2b=a+y時,使用模式一將Z和Y移動過橋。

這兩個模式是把最慢的兩個人送過河,其他人原地不動最省時的兩種可能的方法。
這樣就使問題轉變爲N-2個旅行者的情形,從而遞歸解決之。
     ……         
    A Z →          
    A ←

    A Y →          
    A ←          
    ……

也就是“由A護送到對岸,A返回”,稱作“模式一”。

模式一所用的時間是z+a+c+a

    ……          
    ……  
第n-2步:   A B →   
第n-1步:    A ←    
第n步:     Y Z →  
第n+1步:    B ←          
    ……
這個模式是“由A和B護送到對岸,A和B返回”,稱作“模式二”。

模式二所用的時間是b+d+a+b

比較兩個模式所使用的時間,便可得出:

當2b>a+y時,使用模式一將Z和Y移動過橋;    
 當2b<a+y時,使用模式二將Z和Y移動過橋;    
 當2b=a+y時,使用模式一將Z和Y移動過橋。


算法代碼:

#include <vector>
int TravelBridge(std::vector<int> times)
{
	// 假設時間數組已經排序
	size_t 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 totaltime;
	}
}

參考鏈接:http://blog.csdn.net/wcyoot/article/details/6428248


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章