Case02——POJ1700——快速渡河问题
A group of N people wishes to go across a river with only one boat, which can at most carry two persons.
Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross.
Each person has a different rowing speed; the speed of a couple is determined by the speed of the slower one.
Your job is to determine a strategy that minimizes the time for these people to get across.
Input
The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases.
Then T cases follow.
The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river.
Each case is preceded by a blank line. There won’t be more than 1000 people and nobody takes more than 100 seconds to cross.
Output
For each test case, print a line containing the total number of seconds required for all the N people to cross the river.
Sample Input
1
4
1 2 5 10
Sample Output
17
思路
题目是英文,意思就是说,N个人,两两过河,用时为最慢的那人,然后回来1人,问你最短多长时间能过去,根据上一节的认识,我们已经知道贪心算法,知道题,我们可以很好的想到,当有4个人,如题中给的数据,
我们可以让1和2先过,用时为2,
再让1回来,用时为1,
再让5和10过去,用时为10,
再让2回来,用时为2,
1和2在过去,用时为2,
总用时为2+1+10+2+2=17,
用字母表示为3b+a+d符合题意。
同时我们也可以让a和c先过去,用时为c,
让a回来,用时为a,
再让a和d过去,用时为d,
a回来,用时为a,
a和b过去,用时为b
总用时为5+1+10+2+1
字母表示为 2a+b+c+d,这种方案我们可以很容易想到,就是每次都用用最快的,
这两种方案两两相减,2b和a+c两两比较,都是相对较优的方案,故我们可以具体问题具体分析。
上代码
package greed_dynamic;
import static java.lang.Math.min;
import java.util.Arrays;
import java.util.Scanner;
public class Pra {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for (int i = 0; i < T; i++) {
int n = sc.nextInt();
int[] arr = new int[n];
for (int j = 0; j < arr.length; j++) {
arr[j] = sc.nextInt();
}
Arrays.sort(arr);
solve(arr);
}
}
private static void solve(int[] arr) {
int left = arr.length ;
int res = 0;
while (left > 0) {
if (left==1) {
res += arr[0] ;
break;
} else if (left == 2) {
res += arr[1];
break;
} else if (left == 3) {
res += arr[1] + arr[0] + arr[2];
break;
} else {
//1,2出发,1返回,最后两名出发,2返回
int s1 = arr[1] + arr[0] + arr[left-1] + arr[1];
//1,3出发,1返回,1,4出发,1返回,1,2返回
int s2 = arr[left - 1] + arr[left - 2] + 2*arr[0];
res += min(s1,s2);
left -= 2;
}
}
System.out.println(res);
}
}