楼梯算法 -- 重在思想

前一段时间遇到了一个算法题,印象非常深刻,题目也很简单:

一个人上楼梯,可以一次跨一阶楼梯,也可以一次跨两阶,但是最多一次跨三阶楼梯,请问,在 n 层楼梯的条件下,一个人上楼梯总共有几种方式?

举个例子: 比方说有 1 层楼梯,一个人只能跨一阶上去,也就是只有 1 种上楼梯的方法;

                若有 2 层楼梯,那么可以一阶一阶地上,也可以一次跨两阶,也就是有 2 种上楼梯的方法;

                若有 3 层楼梯,那么可以一阶一阶地上,也可以先跨两阶+后跨一阶,同样也能先跨一阶+后跨两阶,还可以一次跨三阶,也就是有 4 种上楼梯的方法;

                。。。

 

那么如果有 n 层,那有几种上方呢??(附加:可以都列出来吗?)

 

思路:对于 n 层楼梯,分为三种情况:

1> 第一脚跨了一阶楼梯,那么就有 F(n - 1) 种上法(F 作为这个未知函数,返回 n 层楼梯有几种上法);

2> 第一脚跨了两阶楼梯,那么就有 F(n - 2) 种上法;

3> 第一脚跨了三阶楼梯,那么就有 F(n - 3) 种上法。

 

故:F(n) = F(n - 1) + F(n - 2) + F(n - 3)

 

有了这个关系,相信写出一个递归地求几种上法的函数就不难了吧?

 

关键是:怎样把它们都列出来呢?

我试着用 JS 小小地实现了一下,效率不太高,仅供参考下,期待更好的答案。^ ^

(function(n){
	var t = [];
	if(n < 4)
		return n == 1 ? [1] : (n ==2 ? [11, 2] : [111, 12, 21, 3]);
	t[n] = [];
	for(var i = 1; i < 4; i ++){
		for(var j = 0, len = arguments.callee(n - i).length; j < len; j ++){
			t[n].push(String(i) + arguments.callee(n - i)[j]);
		}
	}
	return t[n];
})(6);

运行结果:

["111111", "11112", "11121", "1113", "11211", "1122", "1131", "12111", "1212", "1221", "123", "1311", "132", "21111", "2112", "2121", "213", "2211", "222", "231", "3111", "312", "321", "33"]

posted @ 2011-04-20 17:05  无墨来点睛  Views(3165)  Comments(4Edit  收藏  举报