最快过桥问题

题目:

4个人在晚上过一座小桥,过桥时必须要用到手电筒,只有一枚手电筒,每次最多只可以有两人通过, 4个人的过桥速度分别为1分钟、2分钟、5分钟、10分钟,试问最少需要多长时间4人才可以全部通过小桥?

 

抽象:

N个人过桥,每个人过桥需要的时间为ti(1<=i<=N).每次最多两个人过桥,并且还要回来一个。求最快过桥时间。

 

输入:每人过桥时间数组,人数(数组元素个数)。

输出:最快时间。

 

解析:

 

最佳方案构造:以下是构造N个人(N≥1)过桥最佳方案的方法:  
1) 如果N=1、2,所有人直接过桥。  
2) 如果N=3,由最快的人往返一次把其他两人送过河。  
3) 如果N≥4,设A、B为走得最快和次快的旅行者,过桥所需时间分别为a、b;
 而Z、Y为走得最慢和次慢的旅行者,过桥所需时间分别为z、y。那么    
 当2b>a+y时,使用模式一将Z和Y移动过桥;    
 当2b<a+y时,使用模式二将Z和Y移动过桥;    
 当2b=a+y时,使用模式一将Z和Y移动过桥。

这两个模式是把最慢的两个人送过河,其他人原地不动最省时的两种可能的方法。
这样就使问题转变为N-2个旅行者的情形,从而递归解决之。
     ……         
    A Z →          
    A ←

    A Y →          
    A ←          
    ……

也就是“由A护送到对岸,A返回”,称作“模式一”。

模式一所用的时间是z+a+c+a

    ……          
    ……  
第n-2步:   A B →   
第n-1步:    A ←    
第n步:     Y Z →  
第n+1步:    B ←          
    ……
这个模式是“由A和B护送到对岸,A和B返回”,称作“模式二”。

模式二所用的时间是b+d+a+b

比较两个模式所使用的时间,便可得出:

当2b>a+y时,使用模式一将Z和Y移动过桥;    
 当2b<a+y时,使用模式二将Z和Y移动过桥;    
 当2b=a+y时,使用模式一将Z和Y移动过桥。


算法代码:

#include <vector>
int TravelBridge(std::vector<int> times)
{
	// 假设时间数组已经排序
	size_t length = times.size();
	if(length <= 2)
		return times[length-1];
	else if(length == 3)
	{
		return times[0] + times[1] + times[2];
	}
	else
	{
		int totaltime = 0;
		int a = times[0];
		int b = times[1];
		int z = times[length-1];
		int y = times[length-2];
		if(b*2 < a + y)
		{
			times.erase(times.end()-1);
			times.erase(times.end()-1);
			totaltime += b + a + z + b + TravelBridge(times);
		}
		else
		{
			times.erase(times.end()-1);
			totaltime += z + a + TravelBridge(times);
		}
		return totaltime;
	}
}

参考链接:http://blog.csdn.net/wcyoot/article/details/6428248


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值