边有一条小船。 船太小了,一次只能乘坐两人。每个人都有一个渡河时间T,船划到对岸的时间等于船上渡河时间较
长的人所用时间, 现在已知N个人的渡河时间T,Oliver想要你告诉他,他们最少要花费多少时间,才能使所有人都过河。
注意,只有船在东岸(西岸)的人才能坐上船划到对岸。
解题:
假设N个旅行者的过河时间分别为(已排序){T0, T2, T3, T4 ... T[n-1]},N个旅行者过河的最快时间为sum。 从简单入手,如果N = 1, sum = T1;如果N = 2, sum = max(T1, T2);如果N = 3, sum = T1+T2+T3。如果N > 3,考虑最慢和次慢两个人的过河方法。共有两种方案。
第一种,最快和次快的人先过去(用时T[1]),然后最快的人回来(用时T[0]),接着最慢和次慢的人过去(用时T[n-1]),最后次快的人回来(用时T[1],然后一起过去(用时T[1])。整理后为T[0] + T[1] + T[1] + T[n-1]+T[1]。
第二种,最快和最慢的过去(用时T[n-1]),然后最快的回来(用时T[0]),接着最快和次慢的人过去(用时T[n-2]),最后最快的人回来(用时T[0]),然后一起过去(用时T[1])。整理后为T[0] + T[0] + T[n-1] + T[n-2]+T[1]。
递归解法:
int crossRiver(int *T,int n)
{
if (n==1)
{
return T[0];
}
else if(n == 2)
{
return T[0] + T[1];
}
else if(n == 3)
{
return T[0] + T[1]+T[2];
}
else{
int t1 = T[0] + T[1] + T[1] + T[n - 1]+T[1]; //方案1
int t2 = T[0] + T[0] + T[n - 1] + T[n - 2]+T[1]; //方案2
int t = t1 > t2 ? t2 : t1;
return crossRiver(T, n - 2) + t;
}
}
int ShortTime(int T[],int n)
{
sort(T, T + n);//排个序
if (n==1)
{
return T[0];
}
else if (n==2)
{
return T[1];
}
else if (n==3)
{
return T[0] + T[1] + T[2];
}
else{
return crossRiver(T, n);
}
}