问题描述:四个人打算过一座吊桥,开始时他们都位于该桥的一侧。天很黑,四个人手里只有一个手电筒。该桥一次最多只能同时过两个人,无论是一个人还是两个人过桥,都需要携带手电筒看路。而且手电筒只能通过人携带过桥的方式传递。第一个人过桥需要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)
这是一个关于四个人利用一个手电筒过吊桥的问题,其中每个人过桥所需时间不同。文章提出了两种策略,一种基于贪心算法,另一种通过比较不同组合过桥时间来优化方案。作者提供了Python代码来实现这两种策略,以解决如何在17分钟内让所有人都过桥的问题。
1131





