题目描述
-
N个人希望只乘一条船过河,每条船最多只能载两个人。因此,必须安排谁去与回来,以便所有人最快过河。每个人都有不同的划船速度;两个人速度取决于较慢者。请给出时间最短的策略。
-
输入值
输入的第一行包含一个整数T(1 <= T <= 20),即测试用例的数量。然后是T例。每例的第一行N,第二行包含N个人过河的秒数。每个案例前面都有一个空白行。人数不超过1000,每人的时间不超过100秒 -
输出量
对于每个测试用例,打印一行N个人穿过河流所需的总秒数。
解析
由于渡河速度取决于两个人中速度最慢的量,则可每次优先将最慢的两个人送到对岸,那么渡河可分为两种情况:
①由最快的人带最慢的两个人过河
②最快的两人坐一条船,速度最快的回去,最慢的两人单独坐一条船,由速度第二快的人划回
代码
static int times;
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int T=scanner.nextInt();
int[][] cases=new int[T][];
for (int i = 0; i < T; i++) {
int N=scanner.nextInt();
int[] speed=new int[N];
for (int j = 0; j < N ; j++) {
speed[j]=scanner.nextInt();
}
cases[i]=speed;
}
for (int i = 0; i < cases.length; i++) {
times=0;
solve(cases[i],cases[i].length);
}
}
private static void solve(int[] speed,int cntOfPerple) {
Arrays.sort(speed);
while (cntOfPerple>0) {
if(cntOfPerple==1) {
times+=speed[0];
System.out.println(times);
return ;
}
if (cntOfPerple==2) {
times+=speed[1];
System.out.println(times);
return;
}
if(cntOfPerple==3) {
int a=speed[0]+speed[1]+speed[2];
int b=speed[1]+speed[1]+speed[2];
times+=minOf(a,b);
System.out.println(times);
//退出循环
return;
}
//最慢两个先通过方法
if((speed[0]+2*speed[1]+speed[cntOfPerple-1])<(2*speed[0]+speed[cntOfPerple-2]+speed[cntOfPerple-1])) {
times+=speed[0]+2*speed[1]+speed[cntOfPerple-1];
//每次送过去最后两人
cntOfPerple-=2;
}else {
times+=2*speed[0]+speed[cntOfPerple-2]+speed[cntOfPerple-1];
}
}
}
private static int minOf(int a, int b) {
if(a>=b)
return b;
return a;
}