這樣說可能有些費解,尤其對於初學者來說,接觸這道題的時間可能還未觸及資料結構的層次,或者有所耳聞,但是卻沒有沒法有足夠的模擬和抽象化的能力理解棧是怎樣執行的,那麼我們就從這道題開始,盡量讓你用一道題就掌握棧這個資料結構
有n級的台階,你一開始在底部,每次可以向上邁最多k級台階(最少1級),問到達第n級台階有多少種不同方式。
一開始遇到這道題,我們首先要模擬一下真實上樓梯的情景
k=2 : 1 2 3 5 8 13 21 34…
k=3 : 1 2 4 7 13 24 44 81…
k=4 : 1 2 4 8 15 29 56 108…
k=5 : 1 2 4 8 16 31 61 120…
我們用第乙個例子:當你有1-2級步數的選擇時,你在第一級台階,只有一種選擇,就是從地面邁一步走到第一級。你在第二級台階時,其實有兩種選擇,一種選擇是從第一級邁一步到第二級,或者是從地面邁兩步到第二級。這時我們應該注意,從第一級賣到第二級,我們是沒有考慮從地面到第一級一共有多少中方式的。雖然顯而易見,只有一種。但如果我們是從第10級台階到第11級台階呢?我們依舊可以忽略是怎麼從地面到第10級的,我們只需要知道從第10級只要一步就可以到第11級。那麼到達第11級的方法之一就是先走到第10級,然後再邁一步。為什麼說是方法之一呢?如果說你可以選擇一次走兩步呢?那麼就可以從第9級一次邁兩步到第11級。這時你可能會像,那麼邁的這兩步,是邁兩次一步還是一次兩步?多慮了,你要是邁了一步,你就到了第10級,再邁一步,那就是我說的第一種情況包含的方法數了。我們可以看出,只需要統計出從底層階梯,在步數允許的範圍內,一次邁到我們目標階梯的情況就可以了。
我們用f(n)表示到第幾台階的方法數,現在的假設是我們要上到第6個台階,有1-3種步數可以選擇。
那麼開始模擬
f(0)=1 從地面出發,可以直接到1-3級台階
f(1)=f(0)=1 儲存到第1級台階的方法數
這實際上就是乙個簡單的棧的結構。什麼意思呢?
你在第6級台階,想知道一共有多少種方法,那你要知道f5 f4 f3的一共囊括了多少種方法。以此類推。
計算機是怎麼處理的呢?
6->5->4->3->2->1
到底了,這是從地面到第5級台階的傳遞鏈條,我們要一步步地將資料返回第5層,可是在返回的過程中,我們會遇到很多的分支,怎麼辦呢?我們必須要遍歷這些分支,因為要獲取底層的資料,才能得出上一層的資料,我知道了f1和f0,我才能知道f2。
其實這時候我們就會想,如果我多次遇到比如f3,我難道要再每次都找一遍f3的值是多少嗎?f3找f2,f2找f1,f1找f0,才知道f3是多少。不需要,我們可以用陣列存起來,呼叫的時候,就不用再麻煩了。其實這個過程在下方的**是全程使用的,但是如果在函式方法中,這個方法有個高階的名字叫做記憶化搜尋,其目的是剪枝。如果感興趣的話,你可以自己學習一下,不過這些東西很快隨著你的深入就逐漸接觸了,理解棧這個概念並不需要(其實用函式來理解棧是最好的,但是也是最麻煩的,這裡我就不在贅述(其實是我目前沒能力講清楚,也不想在一篇就把整個體系講完))。
棧的定義是後進後出,你可以想象五個人進入了死胡同,1號先進,2號後進,最後是5號.大家意識到了,要出去的時候,誰先出?只能是5->4->3->2->1的順序。這就是棧這個資料結構了。
這樣做在計算機中有什麼好處?我們要理解棧,不能靠上文這麼一說,不知道怎麼執行的,我們永遠沒法真正掌握棧的真諦。
計算機中,呼叫很重要。
假如一號程式進入了為程式建造的空間中,一號程式要知道某些東西,需要二號程式,就把二號程式拉近空間,然後類推,一直問到了五號,五號說他知道,告訴了四號,五號沒用了,就可以出去了,四號知道了,告訴三號,他也出去了。一直到了一號,一號知道了,告訴了螢幕前的你,他也出去了。
這時最簡單的線性呼叫,就是乙個長條,我們要解決的是樹狀的呼叫
一號想知道乙個問題,需要問
二、三、四號,二號需要知道,需要問更多人。如果畫出圖來,很大一棵數,就像我上圖一樣(上圖其實是有省略的,如果你仔細讀了我的文章,我說過,我用了類似記憶化搜尋的方式簡化了這顆樹)怎麼辦呢?如果在計算機中畫一棵樹,那別的無關資料怎麼儲存?插空嗎?顯然容易出錯,為了計算機執行穩定,需要資料都是線性的儲存。如何線性?還是棧,棧能保證資料時時刻刻都是線性的:
以下是乙個棧的運**況,用題目中給的情況,不考慮記憶化搜尋。
66->5
6->5->4-
6->5->4->3-
6->5->4->3->2
6->5->4->3->2->1
6->5->4->3->2
6->5->4->3->2->0
6->5->4->3->2
6->5->4->3
6->5->4->3->1
6->5->4->3
6->5->4->3->0
6->5->4->3
6->5->4
6->5->4->2
6->5->4->2->1
6->5->4->2
6->5->4->2->0
6->5->4->2
6->5->4
6->5->4->1
6->5->4->1->0
6->5->4->1
6->5->4
6->5
6->5->3
6->5->3->2
6->5->3->2->1
6->5->3->2->1->0
6->5->3->2->1
6->5->3->1
6->5->3->1->0
6->5->3->1
6->5->3
6->5->2
6->5->2->1
6->5->2->1->0
6->5->2->1
6->5->2
6->5
66->4
6->4->3->2->1->0
6->4->3->2->1
6->4->3->2
6->4->3->2->0
6->4->3->2
6->4->3
6->4->3->1
6->4->3->1->0
6->4->3->1
6->4->3
6->4->3->0
6->4->3
6->4
………………………………
我實在是打不動了
最後到了
6從哪開始就從哪結束
甚至你會發現這始終都是一條的棧這個結構,長度是對稱的,前提是你把所有的鏈條都描繪出來。(你也可以寫個程式)
//上樓梯問題
#include
intmain()
;//將在某一台階向下走的方法數全部初始化為零
for(
int i=
1;i<=range_of_steps;i++
)//當階梯數小於等可於以選擇的步數時
store[i]
=store[i]+1
;//f(5)=f(4)+f(3)+f(2)+f(1)+1 加上1,因為從第五級台階可以一步走下去
}for
(int i=range_of_steps+
1;i<=stairs;i++
)// 那麼我們就只能從f(1)處,選擇跨5步到f(6),從f(2)處,選擇跨4步到f(6)以此類推
}printf
("%d"
,store[stairs]);
//我們到了最後乙個階梯,可以回顧一共有多少種方法上到最後乙個台階了
}
N階樓梯上樓問題
n階樓梯上樓問題 一次可以走兩階或一階,問有多少種上樓方式。要求採用非遞迴 輸入包括乙個整數n,1 n 90 可能有多組測試資料,對於每組資料,輸出當樓梯階數是n時的上樓方式個數。示例1 4 5 此題考查的是斐波那契數列。對於n階的樓梯,設其上樓方法有f n 種方法。上到n階,只能從n 1階上一階,...
華科 上樓梯問題
好氣啊!這麼簡單的dp都不會了!這不就是斐波那契數列嗎!f n f n 1 f n 2 因為n層的種類數 於兩種情況,一種是從n 1層上來的,一種是從n 2層上來的,一加就完事兒了。初始條件f 1 1,f 2 2!好氣啊!自己太菜了.n階樓梯上樓問題 一次可以走兩階或一階,問有多少種上樓方式。要求採...
上樓梯 溢位問題
有個小孩正在上樓梯,樓梯有n階台階,小孩一次可以上1階 2階 3階。請實現乙個方法,計算小孩有多少種上樓的方式。為了防止溢位,請將結果mod 1000000007 給定乙個正整數int n,請返回乙個數,代表上樓的方式數。保證n小於等於100000。a i a i 1 a i 2 100000000...