中间一堆是论证过程,不爱看就略过,答案是40,路径直接看最后粗体部分。
第二次被推荐回答了。这个问题百度上搜(n人过桥问题)答案挺多的啊。
还有一些回答说让速度最快的一直当跑腿(贪婪算法),这个思路挺好,但对过桥问题不适用。
解决n人过桥问题前需要证明一个结论(以下称为结论X):回桥的人必然是速度最快的两人之一。
反证法:
约定从左岸到右岸为过桥,从右岸到左岸为回桥。假定最快的两人A、B耗时a、b,如果C(耗时c)走过一次回桥,那么在这之前C以至少c的时间和某人(假定D)过桥至少一次,那么那次过桥完全可以由A或B代替C来陪D走。然后之后除了把C替换为A或B,其他的操作保持一致,既可得到更短的整体时间,问题得证。
也许就有人问了,如果CD过桥时候AB正好在右岸呢,这种情况说明在这之前有一个E走了回桥,无缝转化到对E的讨论上。
接下来是对过桥问题的讨论正篇。
因为论证过结论X,所以说除了A、B外,其他人仅走过一次过桥,而过桥总次数n-1
1、考虑到四人A、B、C、D(按时间升序),最快过桥策略只有两种
a. 去AB,回A,去CD,回B,去AB,用时b+a+d+b+b
b. 去AB,回A,去AC,回A,去AD,用时b+a+c+a+d
显然当c+a>2b时方案1优先,否则方案2优先
2、考虑到三人A、B、C,最快过桥策略不言而喻。
以题主问题为例,其最快策略为
去AB,回A,去FG,回B,去AC,回A,去AD,回A,去AE,回A,去AB
用时4+1+9+4+5+1+5+1+5+1+4=40
补充:看到问题好像是要代码,在这
cost = sorted([1,4,5,5,5,8,9]) # 先按耗时排个序
alltime = 0
for i in range(len(cost)-1,2,-2): # 每次考虑最快的两人和最慢的两人
if cost[i-1] + cost[0] > 2*cost[1]:
alltime += 2 * cost[1] + cost[0] + cost[i]
else:
alltime += 2 * cost[0] + cost[i] + cost[i-1]
# 循环结束后应该还有2或3人没有过桥,相应处理就行了
if len(cost) % 2 == 0:
alltime += cost[0] + cost[1]
else:
alltime += cost[0] + cost[1] + cost[2]
print(alltime)