n人过桥问题

n人过桥问题(Java)

过桥的两种方案

  • 方案一:最快的和最慢的过桥,回来最快的,然后最快的和次慢的过桥,回来最快的。(明显的贪心法,好处:回来得快。)
  • 方案二:最快的人和次快的先过桥,回来最快的,然后最慢的两个过桥,回来次快的。(好处:快的不会最慢的拖累)

判断当前使用那种过桥方案

当前如何过桥跟当前还未过桥的人数有关,主要分三大情况:

  • 人数大于3:如果方案一time<方案二time ,使用方案一,否则使用方案二
  • 人数等于2:直接两人过桥
  • 人数等于3:方案一等价于方案二,并且最后不用回来一个人(因为运完了)。直接将三个人时间加起来即可

动态规划法

子问题的划分

根据上面的情况分析,划分子问题:

  • 根据人数划分过桥情况
  • 根据当前未过桥人用时划分使用方案
代码
 public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(); // 读取人数
        int[] nums = new int[n+1];
        Arrays.sort(nums);
        for (int i = 1; i <= n; i++) {
            nums[i] = sc.nextInt();
        }
        int result = 0;
        int stay = n;
     	//大于三人
        while(stay > 3){
            //判断方案一快还是方案二,这里不等式化简了,自己写一下就知道了。
            if(nums[1] + nums[stay-1] > 2*nums[2]) {
                // 第二种方案
                result += 2*nums[2] + nums[stay] + nums[1];
            } else {
                // 第一种方案
                result += 2*nums[1] + nums[stay] + nums[stay-1];
            }
            //过桥了两人
            stay -= 2;
        }
     
        if (stay == 3){
            result += (nums[1] + nums[2] + nums[3]);
        } else {
            result += (nums[2]);
        }
        System.out.println("最短时间: " + result);
    }

贪心算法

子问题的划分

根据上面的情况分析,划分子问题:

  • 根据人数划分过桥情况。
  • 只根据人数划分的情况使用方案一(贪心法)。
代码
 public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(); // 读取人数
        int[] nums = new int[n+1];
     	//先排序
        Arrays.sort(nums);
        for (int i = 1; i <= n; i++) {
            nums[i] = sc.nextInt();
        }
        int result = 0;
        int stay = n;
     	//大于三人
        while(stay > 3){
            //只使用方案二
            result += 2*nums[1] + nums[stay] + nums[stay-1];
            //过桥了两人
            stay -= 2;
        }
     
        if (stay == 3){
            result += (nums[1] + nums[2] + nums[3]);
        } else {
            result += (nums[2]);
        }
        System.out.println("最短时间: " + result);
    }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值