Cases02_POJ1700_快速渡河问题

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);
	    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值