为了机试开始苦逼学习算法。。。学习过程中记录下一些对问题的理解,有些问题网上虽然有很多答案,不过大多千篇一律,有很多难以理解的地方,这里着重理解,具体的算法还是参考其他人吧。
问题:在一个夜黑风高的晚上,有n(n <= 50)个小朋友在桥的这边,现在他们需要过桥,但是由于桥很窄,每次只允许不大于两人通过,他们只有一个手电筒,所以每次过桥的两个人需要把手电筒带回来,i号小朋友过桥的时间为T[i],两个人过桥的总时间为二者中时间长者。问所有小朋友过桥的总时间最短是多少。
最终大家都能得到这个递归方程: opt[i] = min{opt[i-1] + a[1] + a[i] , opt[i-2] + a[1] + a[i] + 2a[2] }
opt[i-1] + a[1] + a[i] 是第一项
opt[i-2] + a[1] + a[i] + 2a[2] 是第二项
但是这个方程让人难以理解,我对这个方程有两个疑问:
1、剩下1个人的那个情况不应该是已经包含了剩下两个人的情况了吗
2、剩下两个人的情况里,让a[1]跟a[i]一起回去,再让a[1]送一次手电筒不行吗,这样的时间应该是opt[i-2] + a[1] + a[i] + a[1] + a[i-1]
仔细思考,这两个问题实际上指向了同个问题。其实确实最终的情况应该是只剩一个人,哪怕在剩两个人的情况的中间过程中也是只剩下一个人,但是这里会出现选择上的问题,也就是我的问题2,到底该让谁先回去,是a[i]跟某个人一块过河,还是让a[i]跟a[1]一块过河,其中第二个选择跟递归方程的第一项是一样的,第一个选择是不一样的,所以实际上opt[i-2] + a[1] + a[i] + a[1] + a[i-1]可以合并为opt[i-1] + a[1] + a[i](从数学角度也好理解),所以这里直接就写opt[i-2] + a[1] + a[i] + 2a[2]就好了,因为另一个情况已经在opt[i-1] + a[1] + a[i] 中体现了。
刚刚开始学习算法,还有很多需要理解的地方啊。。。。