題目:
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