算法谜题——夜过吊桥代码实现
2014-06-12 22:32
337 查看
问题描述:四个人打算过一座吊桥,开始时他们都位于该桥的一侧。天很黑,四个人手里只有一个手电筒。该桥一次最多只能同时过两个人,无论是一个人还是两个人过桥,都需要携带手电筒看路。而且手电筒只能通过人携带过桥的方式传递。第一个人过桥需要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实现代码如下:
想法一:用贪心算法的思想,每次让第一个人分别与其他人一起过桥,然后第一个人再回来送手电筒,这样,总共花费的时间是(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)
相关文章推荐
- [ASP]无限级分类的简单算法实现及代码重点讲解http://bbs.blueidea.com/thread-1982151-1-1.html
- 卡尔曼滤波简介+ 算法实现代码
- 折半查找实现算法二(递归办法)PS:编译后有一个warning,但不影响结果,代码设计上应该还有些问题
- 支持向量机算法及其代码实现
- 关于24点算法的思想和代码实现
- 并行图像细化算法和C代码实现
- Trie树的应用,一道算法问题求解 代码实现
- 数独问题的一种简单算法代码实现
- 以下是关于对称加密算法的C#实现代码,大家可以根据需要更改不同的算法,文中以Rijndael算法为例
- 卡尔曼滤波简介之算法实现代码
- 卡尔曼滤波简介+ 算法实现代码
- 无限级分类的简单算法实现及代码重点讲解(ASP)
- 欧几里得求两个整数最大公约数算法的汇编递归实现代码
- 快速傅里叶变换(FFT)算法C++实现代码
- C++基本算法收集及代码实现
- ASP中通过该日历算法实现的具体代码
- OpenCV下车牌定位算法实现代码(一)
- 转:无限级分类的简单算法实现及代码重点讲解
- 判断回文算法的代码实现
- 卡尔曼滤波简介+ 算法实现代码(转)