【算法】程序猿不写代码是不对的72

本文介绍了一种解决过桥问题的算法,通过分析不同人员过桥速度,采用两种策略进行优化,确保最少时间完成过桥任务。适用于两人一组携带唯一照明设备通过狭窄桥梁的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.kingdz.algorithm.time201706;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <pre>
 * 过桥问题
 * 
 * http://judgecode.com/problems/1005
 * 
 * n persons wish to cross a narrow bridge at night.
 * Unfortunately it’s so dark now they must pass the bridge under the help of a lamp.
 * They have only one lamp, furethermore the bridge is narrow, as a result a maximum of two persons can cross at one time and they must have the lamp with them.
 * Each person walks at his fixed speed, and a pair must walk together at the rate of the slower person.
 * How fast can all the persons pass the bridge?
 * 
 * 下面参考自http://blog.sina.com.cn/s/blog_77dd9d490102vwf3.html
 * 
 * 要么是最快者将最慢的2个送过桥,要么是最快的2个将最慢的2个送过桥。即将过桥的人按其过桥的时间从小到大排列,设为A、B、……Y、Z。其中A和B是最快的二个,Y和Z是最慢的二个。那么就有二种方案:
 * 
 * 方案一 最快者将最慢的2个送过桥
 * 第一步:A和Z过桥,花费Z分钟。
 * 第二步:A回来,花费A分钟。
 * 第三步:A和Y过桥,花费Y分钟。
 * 第四步:A回来,花费A分钟。
 * 这四步后总人数就减小2个,花费时间为A + A + Y + Z分钟。
 * 
 * 方案二 最快的2个将最慢的2个送过桥
 * 第一步:A和B过桥,花费B分钟。
 * 第二步:A回来,花费A分钟。
 * 第三步:Y和Z过桥,花费Z分钟。
 * 第四步:B回来,花费B分钟。
 * 这四步后总人数同样减小2个,花费时间为A + B + B + Z分钟。
 * 
 * 这样,每次比较一下这二种方案就能将总人数减小2。然后我们再考虑一些边界情况:
 * 有三个人过桥设为A、B、C(已经排好序,下同)。应该花费A + B + C分钟。
 * 有二个人过桥设为A、B。那么肯定是花费B分钟。
 * 有一个人过桥设为A。肯定花费A分钟。
 * </pre>
 * 
 * @author kingdz
 * 
 */
public class Algo19 {

	public static void main(String[] args) {
		String input = "1 2 5";
		int total = getTotalTime(input);
		System.out.println("total cost:" + total);
	}

	private static int getTotalTime(String input) {
		List<Integer> list = new ArrayList<Integer>();
		for (String str : input.split(" ")) {
			list.add(Integer.parseInt(str));
		}
		Collections.sort(list);

		int sum = 0;

		while (list.size() > 3) {
			int a = list.get(0);
			int b = list.get(1);
			int z = list.remove(list.size() - 1);
			int y = list.remove(list.size() - 1);
			if (a + y < b + b) {
				sum = sum + a + a + y + z;
			} else {
				sum = sum + a + b + b + z;
			}
		}

		if (list.size() == 1) {
			sum = sum + list.get(0);
		} else if (list.size() == 2) {
			sum = sum + list.get(1);
		} else if (list.size() == 3) {
			sum = sum + list.get(0) + list.get(1) + list.get(2);
		}

		return sum;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值