N个人过河,船每次只能坐两个人,船载每个人过河的所需时间不同t[i],每次过河的时间为船上的人的较慢的那个,问最快的过河时间。(船划过去要有一个人划回来)
最优选择:
先将所有人过河所需的时间按照升序排序,我们考虑把单独过河所需要时间最多的两个旅行者送到对岸去,有两种方式:
1.最快的和次快的过河,然后最快的将船划回来;次慢的和最慢的过河,然后次快的将船划回来,所需时间为:t[0]+2*t[1]+t[n-1];
2.最快的和最慢的过河,然后最快的将船划回来,最快的和次慢的过河,然后最快的将船划回来,所需时间为:2*t[0]+t[n-2]+t[n-1]。
具体实现代码如下所示:
/** * @Title: ShipCrossRiver.java * @Package greedyalgorithm * @Description: TODO * @author peidong * @date 2017-5-19 上午9:03:51 * @version V1.0 */ package greedyalgorithm; import java.util.Arrays; import java.util.Scanner; /** * @ClassName: ShipCrossRiver * @Description:小船过河 * @date 2017-5-19 上午9:03:51 * */ public class ShipCrossRiver { /** * * @Title: compare * @Description: 判断大小 * @param a * @param b * @return * @return boolean * @throws */ public static boolean compare(int a, int b) { return a < b; } /** * @Title: main * @Description: TODO * @param args * @return void * @throws */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("请输入数组长度:"); Scanner sc = new Scanner(System.in); int N = sc.nextInt(); int[] array = new int[N]; System.out.println("请输入数组元素:"); for (int i = 0; i < N; i++) { array[i] = sc.nextInt(); // 输入数组 } Arrays.sort(array); //升序排列 int sum = 0; while (N > 3) { //贪心算法实现 int less = array[0] + 2 * array[1] + array[N - 1]; if ((array[0] + 2 * array[1] + array[N - 1]) > (2 * array[0] + array[N - 2] + array[N - 1])) // 两种方式选择 less = 2 * array[0] + array[N - 2] + array[N - 1]; sum += less; N -= 2; } //边界条件讨论 if (N == 3) { sum += array[0] + array[1] + array[2]; // 只剩三人 } else if (N == 2) { sum += array[1]; // 只剩两人 } else { sum += array[0]; } System.out.println("总过河时间为:" + sum); } }