小朋友过桥问题:在一个夜黑风高的晚上,有n(n <=
50)个小朋友在桥的这边,现在他们需要过桥,但是由于桥很窄,每次只允许不大于两人通过,他们只有一个手电筒,所以每次过桥的两个人需要把手电筒带回来,i号小朋友过桥的时间为T[i],两个人过桥的总时间为二者中时间长者。问所有小朋友过桥的总时间最短是多少。
问题分析:首先将n个小朋友按过河时间从小到大排序,设第i个小朋友过河的时间为T[i]。假设n个小朋友过河的总时间为f(n),则f(1)=T[1];
f(2)=T[2];f(3)=T[2]+T[1]+T[3]。当n=4时,1,2号小朋友过河,时间为T[2]1号小朋友回来,时间为T[1]
3,4号小朋友过河,时间为T[4]2号小朋友回来,时间为T[2]此时,河这边仅有1,2号小朋友,时间为f(2)所以过河总时间f(4)
=T[2]+T[1]+T[4]+T[2]+f(2)
假设有n个小朋友(n>=4):1,2号小朋友过河,时间为T[2]1号小朋友回来,时间为T[1]n-1,n号小朋友过河,时间为T[n]
2号小朋友回来,时间为T[2]此时,河这边有1号到n-2号的所有小朋友,所以时间为f(n-2)所以过河总时间f(n)
=T[2]+T[1]+T[n]+T[2]+f(n-2)
通过以上表述我们可以得到如下递推公式:f(1)=T[1]f(2)=T[2]f(3)=T[1] + T[2] + T[3]
f(n) = T[1]+2T[2]+T[n] + f(n-2); n>=4
实现代码如下:
#include <iostream> #include <algorithm> using namespace std; int
baby_cross_river(int *T, int n) { if(n<=2) return T[n]; if(n == 3) return
T[1]+T[2]+T[3]; int f_n2 = T[2]; //f(n-2) int f_n1 = T[1]+T[2]+T[3];//f(n-1)
int f_n = 0; for(int i = 4; i <= n; ++i) { f_n = T[1] + 2*T[2] + T[i] + f_n2;
f_n2 = f_n1; f_n1 = f_n; } return f_n; } int main() { const int n = 5; int
T[n+1]={0, 1, 2, 5, 10, 20};//start index = 1 int fn = baby_cross_river(T, n);
cout<<"total cost is "<<fn<<endl; return 0; }
热门工具 换一换