算法谜题——夜过吊桥代码实现

这是一个关于四个人利用一个手电筒过吊桥的问题,其中每个人过桥所需时间不同。文章提出了两种策略,一种基于贪心算法,另一种通过比较不同组合过桥时间来优化方案。作者提供了Python代码来实现这两种策略,以解决如何在17分钟内让所有人都过桥的问题。

问题描述:四个人打算过一座吊桥,开始时他们都位于该桥的一侧。天很黑,四个人手里只有一个手电筒。该桥一次最多只能同时过两个人,无论是一个人还是两个人过桥,都需要携带手电筒看路。而且手电筒只能通过人携带过桥的方式传递。第一个人过桥需要1分钟时间,第二个人过桥需要2分钟,第三个人需要5分钟,第四个需要10分钟。由于速度不同,两个人一起过桥的话,速度以慢的人为准。例如,如果第一个人和第四个人一起过桥,两个人到达对岸需要10分钟,如果让4号走回来返还手电筒,则还需要10分钟。这一共就花了20分钟。问他们四人能在17分钟内过桥吗?


想法一:用贪心算法的思想,每次让第一个人分别与其他人一起过桥,然后第一个人再回来送手电筒,这样,总共花费的时间是(2+1)+(5+1)+(10)=19分钟


想法二:把两次过桥和送手电筒作为一个回合,考虑下面两种方式的时间:

(假设X,Y为最慢和次慢的过桥者,x,y为最快和次快的过桥者。)

A:用最快的X陪同最慢和次慢的x,y过桥。

     也就是第一步x,X过桥,x回头(花费x+X分钟);

             第二步x,Y过桥,x回头(花费Y+x分钟);

    这种方式一次花掉2*x+X+Y分钟。

B:用最快和次快的x,y陪同最慢和次慢的X,Y过桥。

     也就是第一步x,y过桥,x回头(花费x+y分钟);

             第二步X,Y过桥,y回头(花费X+y分钟);

    这种方式一次花掉x+2*y+X分钟。

显然上面的两种方法,当2*x+X+Y<x+2*y+X的时候,选A否则选B过桥。

上述方法用python实现代码如下:

def function1(left,right,sum):
		left.sort()
		print '%d ,%d cross the bridge' % (left[0],left[1])
		x=left.pop(0)
		y=left.pop(0)
		right.extend([x,y])
		right.sort()
		sum+=max(x,y)
		print '%d go back to the left' %right[0]
		z=right.pop(0)
		left.extend([z])
		left.sort()
		sum+=z
		print '%d ,%d cross the bridge' % (left[len(left)-1],len(left)-2)
		x=left.pop(len(left)-1)
		y=left.pop(len(left)-1)
		right.extend([x,y])
		right.sort()
		sum+=max(x,y)	
		if len(left)!=0:	
				print '%d go back to the left' %right[0]
				z=right.pop(0)
				left.extend([z])
				sum+=z
		return sum		
		
def function2(left,right,sum):
		left.sort()
		print '%d ,%d cross the bridge' % (left[0],left[len(left)-1])
		x=left.pop(0)
		y=left.pop(len(left)-1)
		right.extend([x,y])
		right.sort()
		sum+=y
		print '%d go back to the left' %right[0]
		z=right.pop(0)
		left.extend([z])
		left.sort()
		sum+=z
		print '%d ,%d cross the bridge' % (left[0],left[len(left)-1])
		x=left.pop(0)
		y=left.pop(len(left)-1)
		right.extend([x,y])
		right.sort()
		sum+=y
		if len(left)!=0:
				print '%d go back to the left' %right[0]
				z=right.pop(0)
				left.extend([z])
				sum+=z
		return sum
		

def cross_bridge(left):
		sum=0
		right=[]
		left.sort()
		min1=left[0]
		min2=left[1]
		max1=left[len(left)-1]
		max2=left[len(left)-2]
		while len(left)>2:
				if 2*min1+max1+max2<min1+2*min2+max1:
						sum=function2(left,right,sum)
						#print sum
				else:
						sum=function1(left,right,sum)
						#print sum
		print '%d ,%d cross the bridge' % (left[0],left[1])
		sum+=left[1]
		print 'All time used is %d' %sum
		
def max(a,b):
		if a>b:
				return a
		else:
				return b		
				
left=[1,2,5,10]
cross_bridge(left)




评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值