問題
剛才在首頁看到一篇博客,說的是騰訊的一道面試題:一個樓梯有50個台階,每一步可以走一個台階,也可以走兩個台階,請問走完這個樓梯共有多少種方法?博主把這題分析的很麻煩。引來很多人圍觀。我以前也碰到過這個問題。寫出來和大家分享一下。
舉個例子,假設有3個台階,則有三種走法:分別是,1-1-1, 1-2, 2-1。
分析
很簡單的一道題,學過組合數學的人很快就能想到,這是一個遞推關系。假設走完k個台階有f(k)種走法。
- k = 1時,f(k) = 1
- k = 2時,f(k) = 2
- k = n時,第一步走一個台階,剩n-1個台階,有f(n - 1)種走法。第一步走兩個台階,剩n-2個台階,有f(n - 2)種走法。所以共有f(n - 1) + f(n - 2)種走法。
於是有如下公式
代碼
int count(unsigned int n)
{
if(n ==1)
return1 ;
if(n ==2)
return2 ;
else
return count(n -1) + count(n -2) ;
}
具體是怎么走的呢?
上面只給出了有多少種走法,那么具體每一種走法是怎么走的呢?比如n=4時,五種走法分別如下:
1,1,1,1
1,1,2
1,2,1
2,1,1
2,2
我們用一個整型數組來存放每一步的內容,1表示這步走了一個台階,2表示這步走了兩個台階。回溯法搞定。代碼如下。
void count(int n, int t)
{
if(n <0)
return ;
if (n ==0)
Output(step, t) ;
else
{
for (int i =1; i <=2; ++i)
{
step[t] = i ;
count(n - i, t +1) ;
}
}
}
類似的問題
與此題類似的問題有很多,比如鋪地磚問題,自然數拆分等。
鋪地磚問題
有一個長度為n,寬度為2的地面,有若干塊長為2,寬為1的地磚,請問用此地磚鋪完這個地面共有多少種方法?
分析一下,假設鋪完長度為n的地面有f(n)種方法,如果第一塊地磚豎起來鋪,還剩下長度為n-1的地面,有f(n-1)種方法。如下圖。
如果第一塊地轉橫着鋪,那么還剩下長度為n-2的地面,有f(n-2)種鋪法。如下圖。
所以這道題與上面的題解法完全一樣。不同的題目,相同的模型而已。
自然數拆分
給定一個自然數n,將其拆分為若干個自然數字之和,請問有多少種方法?舉個例子,n=4時,可以拆分為1-1-1-1,1-1-2,1-3,2-2。
這題和上面的題很像,不過上面的問題是排列問題,而這題是組合問題,比如n=4時,1-1-2,1-2-1,2-1-1這三種只能算一個拆分。在上面的基礎上,去掉重復的組合即可。