某夜,有个团伙要过桥,该桥每次只能通行2个人,只有一个手电筒,过桥必须持有手电筒。这些人单独过桥的时间从小到大分别为t1、t2、t3、t4、t5 ………
请写程序计算出这伙人过桥需要的最短时间。(提示:假设是四人,如果t1=1,t2=2,t3=5,t4=10,最短用时为17)
昨天公司领导出了上面逻辑题,看着挺有意思,自己初略思索了下,琢磨最短用时应该19才是,后面某一同事提了个方案:
方式1,t1作为来回传递手电筒,总耗时s1=t2+t1+t3+t1+t4
方式2,借助t1和t2,将t4和t3送过桥的方式,总耗时s2=t2+t1+t4+t2+t2
当s2<s1时,也就是2*t2<t1+t3,采用方式2过桥时间最短,否则方式1更佳!
后来公司领导说,如果推广到5个、N个。。。
心理嘀咕了下,方式2的方式其实是通过t1和t2将最慢的两人t3和t4送过桥而耗时最短,所以理论上不管4个5个还是N个,通过上面的逻辑判断,应该都能做到推广吧,有点晚也就没去验证了。
今早看群里还有同事讨论此事,于是乎自己也感兴趣拿着之前同事群里发的代码做了下修改:
function across_time(args){
var ret = 0;
var _tmp = args.sort(function(a,b){return a-b;});
console.log(_tmp);
if (args.length < 3)
{
ret = Math.max(args[0]||0,args[1]||0);
return ret;
}
if (_tmp.length == 3) {
ret = _tmp[1] + _tmp[0] + _tmp[2];
console.log(ret);
return ret;
}
for(var i=_tmp.length-1;i>0;i=i-2){
if (i >= 3) {
if (2 * _tmp[1] <= _tmp[0] + _tmp[i]) {
ret += _tmp[1] + _tmp[0] + _tmp[i] + _tmp[1] ;
} else {
ret += _tmp[i] + _tmp[0] + _tmp[i - 1] + _tmp[0];
}
}else{
for (var j = i; j > 0; j--) {
ret += _tmp[j];
}
if (i % 2 == 0) {
ret += _tmp[0];
}
}
}
console.log(ret);
return ret;
}
验证了下群里同事发的几组数据,应该没啥问题,编程的乐趣源于思考的过程并从中发现乐趣!
以上仅是个人见解,也许也有问题,欢迎讨论