算法很没:快速渡河问题

题目描述

  • 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;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值