撑船过河(北大oj)

已知有n位同学要过河,他们的速度分别为:7、2、3、6、4.....有一条船,每次最多载两名同学,并且由速度最慢的同学进行划船。

在这里我们先假设有4名同学。

情景一、

当他们的速度分别为2、3、7、1

我们需要对速度先进行排序:1、2、3、7

方法一、

我们先假设每一次都由最快的同学的送

也就是

最快的同学送第二快的同学                 1秒的送2秒的

最快的同学在返回                                 1秒的返回

最快的同学送第三快的同学                 1秒的送3秒的

最快的同学在返回                                  1秒的返回

最快的同学送第四快的同学                  1秒的送7秒的

需要耗费的时间为:2+1+3+1+7=14s

方法二、

最快的同学送第二快的同学                 1秒的送2秒的

最快的同学在返回                                 1秒的返回

最慢的同学送第二慢的同学                   7秒的送3秒的

第二快的同学返回                                    2秒的返回

第一快送第二快的同学                            2秒的送1秒的

需要耗费的时间为:2+1+7+2+2=14s

情景二、

当他们的速度分别为2、2、7、1

我们需要对速度先进行排序:1、2、2、7

方法一、

我们先假设每一次都由最快的同学的送

也就是

最快的同学送第二快的同学                 1秒的送2秒的

最快的同学在返回                                 1秒的返回

最快的同学送第三快的同学                 1秒的送2秒的

最快的同学在返回                                  1秒的返回

最快的同学送第四快的同学                  1秒的送7秒的

需要耗费的时间为:2+1+2+1+7=13s

方法二、

最快的同学送第二快的同学                  1秒的送2秒的

最快的同学在返回                                 1秒的返回

最慢的同学送第二慢的同学                   7秒的送2秒的

第二快的同学返回                                    2秒的返回

第一快送第二快的同学                            2秒的送1秒的

需要耗费的时间为:2+1+7+2+2=14s

我们先定义一个init()方法用于自动生成速度:

 输入过河人数,与人数相对应的数组长度的数组进行初始化

 private void init() {
          System.out.println("请输入要过河的人数");
          Scanner scanner = new Scanner (System.in);
          int n = scanner.nextInt();
          scanner.close();
          int[] times = new int[n];
          for (int i = 0; i < times.length; i++) {
			  times[i] = new Random().nextInt(10)+1;  //因为产生的是0~9的数所以要进行加一
		}

对生成的数组排序,并进行打印

          //对生成的速度进行排序
          Arrays.sort(times);
          //定义生成的数组
          System.out.println(Arrays.toString(times));

我们先将整体的代码进行运行

package AAA;

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class a6 {
    private void init() {
          System.out.println("请输入要过河的人数");
          Scanner scanner = new Scanner (System.in);
          int n = scanner.nextInt();
          scanner.close();
          int[] times = new int[n];
          for (int i = 0; i < times.length; i++) {
			  times[i] = new Random().nextInt(10)+1;  //因为产生的是0~9的数所以要进行加一
		}
          //对生成的速度进行排序
          Arrays.sort(times);
          //定义生成的数组
          System.out.println(Arrays.toString(times));
          
	}
    public static void main(String[] args) {
		new a6().init();
	}
}

 得到的结果为:

请输入要过河的人数
10
[2, 3, 3, 3, 4, 5, 7, 7, 7, 8]

定义一个print(int  n,int [] times)方法

传递过河人数 和 他们过河时间的排序

  private void print(int n,int [] times) {
            int perpol = n; //接收总人数
            int num = 0;//初始化所用时间
          
            
         while(perpol>0) {   //当所有人都过河后跳出循环
            if(perpol==1) { //perpol为1是这个时候只有一个人过河时间也只有一个
            	num  += times[0];
            	break;
            }else if(perpol==2) {//perpol为2的时候,两个人可以一起过去速度最慢的划船
            	num +=times[1]; 
            	break;
            }else if(perpol==3) {
            	//perpol为3的时候,最少三个人都要划船
            	num += times[0] + times[1] + times[2];
            	break;
            }else {
                /*假设他为每趟都是速度最快的陪同
                               *  速度最快的和速度最慢的  
            	  速度最快的返回
            	  速度最快的和速度第二慢的
            	  速度最快的方法*/ 
            	int s1 = 2*times[0] + times[perpol-1] + times[perpol-2];
            	//假设他为先送第二块的在走最慢的
            	/*
            	 * 速度最快的和速度第二快的先过河
            	 * 速度最快的返回
            	 * 速度最慢的和速度第二慢的过河
            	 * 速度第二块的方法
            	 */
            	int s2 = 2*times[1] + times[0] + times[perpol-1];
            	
            	//对两个速度进行比较取最小的
            	int min = Math.min(s1, s2);
            	 perpol -= 2; //每次送走两个人
            	num += min;
            }
         }
	}

我们在init()方法钟调用一下print()方法

package AAA;

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class a6 {
    private void init() {
          System.out.println("请输入要过河的人数");
          Scanner scanner = new Scanner (System.in);
          int n = scanner.nextInt();
          scanner.close();
          int[] times = new int[n];
          for (int i = 0; i < times.length; i++) {
			  times[i] = new Random().nextInt(10)+1;  //因为产生的是0~9的数所以要进行加一
		}
          //对生成的速度进行排序
          Arrays.sort(times);
          //定义生成的数组
          System.out.println(Arrays.toString(times));
          print(n, times);
	}
    private void print(int n,int [] times) {
            int perpol = n; //接收总人数
            int num = 0;//初始化所用时间
          
            
         while(perpol>0) {   //当所有人都过河后跳出循环
            if(perpol==1) { //perpol为1是这个时候只有一个人过河时间也只有一个
            	num  += times[0];
            	break;
            }else if(perpol==2) {//perpol为2的时候,两个人可以一起过去速度最慢的划船
            	num +=times[1]; 
            	break;
            }else if(perpol==3) {
            	//perpol为3的时候,最少三个人都要划船
            	num += times[0] + times[1] + times[2];
            	break;
            }else {
                /*假设他为每趟都是速度最快的陪同
                               *  速度最快的和速度最慢的  
            	  速度最快的返回
            	  速度最快的和速度第二慢的
            	  速度最快的方法*/ 
            	int s1 = 2*times[0] + times[perpol-1] + times[perpol-2];
            	//假设他为先送第二块的在走最慢的
            	/*
            	 * 速度最快的和速度第二快的先过河
            	 * 速度最快的返回
            	 * 速度最慢的和速度第二慢的过河
            	 * 速度第二块的方法
            	 */
            	int s2 = 2*times[1] + times[0] + times[perpol-1];
            	
            	//对两个速度进行比较取最小的
            	int min = Math.min(s1, s2);
            	 perpol -= 2; //每次送走两个人
            	num += min;
            }
         }
         System.out.println("最小耗费"+num+"秒");
	}
    public static void main(String[] args) {
		new a6().init();
	}
}

得到的运行结果为:
 


请输入要过河的人数
10
[1, 1, 2, 2, 2, 5, 6, 8, 8, 9]
最小耗费37秒
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值