走樓梯問題

2021-06-18 16:29:25 字數 4692 閱讀 7468

宣告:題目來自:自己先做一遍。

27. 跳台階問題

題目:乙個台階總共有n級,如果一次可以跳1級,也可以跳2級。

求總共有多少總跳法,並分析演算法的時間複雜度。

這道題最近經常出現,包括microstrategy等比較重視演算法的公司都

曾先後選用過個這道題作為面試題或者筆試題。 

思路:

一開始我想到的方法就是排列組合,假設n是4,那可以跳1次2級,或者2次2級。跳1次2級,可以有3個位置(0代表地面,1代表第乙個台階,4代表第四個台階,所以 這3個可以跳2級的位置分別是 0,1,2),可以寫成c3

1 ,表示從3個位置裡面選乙個位置。跳2次2級的起跳位置呢?0,1,2都可以,那是不是從3個位置中選兩個呢,這樣的話c3

2 的話是3,但是實際上4個台階跳2個2次,只有一種跳法,起跳位置是0和2。我們不能選起跳位置為1的台階。其實我一開始從「選擇合適的起跳位置的」想法就不好,因為並不是所有的位置都適合起跳的,在上面4個台階跳2個2級的情況下,如果有乙個2級是從台階1開始起跳的話,就沒有辦法再放進去乙個2級的跳動了。

我的乙個同事拿到這個問題後,一開始的想法就是借鑑 dynamic programming的思路,就是試圖 把乙個大問題拆成遞迴式的小問題,具體來說:設f(n)表示n個台階一共有f(n)種跳法,那f(n)和f(n-1),f(n-2), 是什麼關係? 這裡只是借鑑了這樣的思路,並不完全是dynamic progamming, dynamic programming需要滿足如果如果f(n)是最優的,並且f(n)可以拆成 f(k)和f(n-k),那麼 f(k)和f(n-k)必須也是最優的。這裡我們並不關係「最優」。

在這個跳樓梯的題目中,每次可以跳1個台階或者2個台階。我們考慮,我們是如何跳到n這個台階的,一共有兩種方式,一種是從n-1台階跳乙個台階,另外一種是從 n-2跳2個台階,所以:

f(n) = f(n-1) + f(n-2)  並且  f(1)=1, f(2) = 2 。

容易看出,其實這就是乙個斐波那契數列。

後續思考:

其實這種解題的思路 和 小學奧數裡面乙個叫做「加法原理」的思路如出一轍。假設有乙個5x4的格仔m,有5行,4列。問從左下角(座標m(1,1)  )走到右上角(座標 m(5,4)  )一共有幾種走法(每次移動只能從左到右,或者從下到上)。

按照題目的要求,到達m(5,4)一共有兩種方法,途徑m(5,3)向右移動一格,或者途徑m(4,4)向上移動一格,所以,如果用f(x,y)表示從m(1,1)到達m(x,y)的路徑總數,那麼:

f(x,y) = f(x, y-1) + f(x-1, y) ,  f(1,1) = 0, f(1,2) = 1, f(2,1) = 1

總結:

清華大學黃高峰曾經寫過一篇總結,我把它貼在這裡:

清華大學黃高峰:謀劃解題策略的幾種典型方法

對於某乙個具體的問題,如何思考分析,從而謀劃策略,是十分重要的。策略的謀劃過程是乙個思維發散的過程。問題本身千變萬化,解決問題的策略也比較多,謀劃策略的方法不一而足,根據人們的思維方式,我們論述以下幾種謀劃策略的思想。

1、降格思想:從對問題的特殊和簡單狀態的分析中歸納出問題的實質內涵或規律,從而得到問題的一般解法,也就是我們常說的"投石問路"或者叫做"嘗試歸納"。這種通過特殊求得一般、通過實際求得抽象的思想在謀劃策略的過程中是十分有效的,特別是當題目中所給的資料比較大或者很抽象而難以入手時,常用這種思想來謀劃策略。

這道題中的台階數為10,雖然不是很大,但一時也很難入手。我們運用降格思想分析這個問題,先看幾種簡單的情形:

a、僅有1級台階時,登法只有1種:一步1級。

b、有2級台階時,登法有2種:一步2級;1級+1級(兩步)。

c、有3級台階時,登法有3種:1級+1級+1級;1級+2級;2級+1級。

這裡"1級+2級"表示先登1級再登2級;"2級+1級"表示先登2級再登1級,顯然這兩種登法是不同的。

d、有4級台階時,登法有5種:

1級+1級+1級+1級;

1級+1級+2級;

1級+2級+1級;

2級+1級+1級;

2級+2級。

e、有5級台階時,登法有8種:

1級+1級+1級+1級+1級;

1級+1級+1級+2級;

1級+1級+2級+1級;

1級+2級+1級+1級;

1級+2級+2級;

2級+1級+1級+1級;

2級+1級+2級;

2級+2級+1級。

按照台階數遞增的次序把登法的種數排列如下:

1,2,3,5,8……

容易想到這是菲波那契數列的一部分,這就找到了問題的規律,同時也謀劃出解決問題的策略:數學模型(規律)策略。容易得到後繼資料是:13,21,34,55,89……,於是得到問題的解:10級台階共有89種登法。

當然,關於找到的規律的正確性必須給出詳細的證明,這裡不再詳述。應用這個例子無非是為了說明從簡單出發考慮問題的優越性,同時指出,敏銳的洞察已有資料的能力對於謀劃策略也是相當重要的。

2、公升格思想:這種思想與第一種思想恰恰相反,它是把一些過於具體的問題抽象化,目的是忽略其中的一些次要因素,從而更好地把握其中的主要因素,通過解決一般問題從而解決具體問題。有時會發生這樣的情況:由於問題中給出的資料過於具體,往往會形成一種思維定勢,一直針對具體的資料進行分析,而忽視了問題中顯而易見的東西。運用這一思想有利於突破思維定勢,更快地找到解決問題的策略,其關鍵是在於對抽象問題的分析和推理。

我們把"台階問題"抽象化,設有n級台階,登台階規則不變。對於登n級台階的最後一步有兩種情況:

(1)由第n-1級台階跨一步(1級)到達第n級;

(2)由第n-2級台階跨一步(2級)到達第n級。

顯然,以上的兩類登法是不同的,n級台階的總登法就是這兩類登法的總和。我們用f(x)表示x級台階的登法種數,則有: f(n)=f(n-1)+f(n-2)以及f(1)=1;f(2)=2。

這就迅速地得到了問題的數學模型,也就謀劃出解決問題的策略:數學模型(規律)策略。

從這個例子的分析中可以看出,對問題的抽象概括,尋求問題的一般解法,對於某些問題的解決是十分簡便的。適當運用公升格思想往往可以"一箭中的",迅速描述出問題的本質,從而得到解決問題的策略。

3、分格思想:把整個問題劃分為幾個相聯絡的子問題或幾個連續的解題步驟,再一一設法解決,最後綜合各個部分的解就可以得到整個問題的解。作為一種思維方法,在分析問題的時候恰當運用,對於謀劃解題策略是很有效的。劃分問題的方法有很多種,最基本的原則是把難以描述的問題化為易於描述的問題,把不易求解的化為易求解的。

仍是看上面的"台階問題",由登10級台階所用的步數不同,可以劃分為如下的幾種情況:

a、共要登10步(全部都是每步登1級):有1種登法;

b、共要登9步(只有某一步登2級,其餘每步登1級):有c9

1=9種登法;

c、共要登8步(只有某兩步每步登2級):有c8

2=28種登法;

d、共要登7步(只有某三步每步登2級):有c7

3=35種登法;

e、共要登6步(只有某四步每步登2級):有c6

4=15種登法;

f、共要登5步(全部都是每步登2級):有c5

5=1種登法;

因此總共的登法有1+9+28+35+15+1=89種。

通過上面的對問題劃分的過程以及計算的結果的分析,我們可以得到以下的兩種策略:

(1)分治策略,直接仿照上面的劃分過程由計算機加以實現。

(2)數學模型(規律)策略,從中歸納出:對於n級台階的登法有幾 種。

通過上面的例子可以看出:分格思想關鍵在乙個"分"字,也就是如何劃分問題,劃分中應注意兩點:

1、劃分必須根據統一的標準,不重複,不遺漏;

2、劃分必須具有啟發性,即對於謀劃問題的策略有一定的啟發作用。

4、變格思想:通過轉換問題某些資訊,從而轉化問題的形式,達到化顯為隱、化繁為簡、化難為易、化未知為已知的目的,通過解決等效問題來解決原問題。

再看上面的"台階問題",我們運用變格思想對問題進行轉化,考慮人在台階上的位置變化,比如:人處於第1台階上時,若一步登1級就可以到達第2級台階;若一步登2級就可以到達第3級台階。我們用點表示每一級台階,用邊表示台階之間可以"一步到達"的關係,就可以得到下面的圖:

於是,問題就轉化為:在圖6中,求從點0到點10的所有路徑總數。這是乙個為我們所熟悉的圖論問題,可以用窮舉策略解決,當然這種策略相對於前面所謀劃的那些策略而言沒有什麼優勢,但畢竟也是解決問題的策略之一。

如果說變格思想在上面的這個例子中的運用相對於其它思想沒有什麼優勢的話,那麼回想一下在解決"最佳航空路線問題"時,我們把它轉化為"最短路徑問題"、"最小費用流問題"就都是變格思想成功運用的例子了。

運用變格思想的關鍵就是要"變"得巧妙,這種思想對於探索新問題,特別是未知問題是很有效的。

以上所說的這些策略的具體演算法在計算機上都是很容易實現的,具體的程式就不再給出了。

--------------------------------------

ps:當然,也可以brute-force遞迴的,思路是這樣的:

void tryjump(int currentstairindex)

tryjump(10)  --> 你會得到g_totalcnt=89, 但是我不推薦這樣的做法。

遞迴 走樓梯

例題 爬樓梯樹老師爬樓梯,他可以每次走1級或者2級,輸入樓梯的級數,求不同的走法數例如 樓梯一共有3級,他可以每次都走一級,或者第一次走一級,第二次走兩級,也可以第一次走兩級,第二次走一級,一共3種方法。輸入 輸入包含若干行,每行包含乙個正整數n,代表樓梯級數,1 n 30輸出不同的走法數,每一行輸...

走樓梯 遞迴

描述 樓梯有n 100 n 0 階台階,上樓時可以一步上1階,也可以一步上2階,也可以一步上3階,程式設計計算共有多少種不同的走法。輸入輸入的每一行包括一組測試資料,即為台階數n。最後一行為0,表示測試結束。輸出每一行輸出對應一行輸入的結果,即為走法的數目。樣例輸入12 340樣例輸出12 47解析...

面試題之走樓梯問題

題目 乙個台階總共有n 級,如果一次可以跳1 級,也可以跳2 級,求總共有多少總跳法,並分析演算法的時間複雜度。注 這道題最近經常出現,包括microsoft 等比較重視演算法的公司都曾先後選用過個這道題作為面試題或者筆試題。思路一 首先我們考慮最簡單的情況 如果只有1 級台階,那顯然只有一種跳法,...