【基礎(chǔ)算法】解決經(jīng)典兔子問(wèn)題的兩種思路

有一個(gè)經(jīng)典的算法問(wèn)題轧飞,題目是這樣的:

有一對(duì)小兔子,當(dāng)小兔子成長(zhǎng)到第三個(gè)月的時(shí)候按厘,每個(gè)月都會(huì)生一對(duì)小兔子纲菌,新生的小兔子同他們的父母具有一樣的生殖性質(zhì)(成長(zhǎng)到第三個(gè)月之后每個(gè)月都生一對(duì)),兔子不會(huì)死亡宝磨,求n個(gè)月后有多少對(duì)兔子弧关。

這個(gè)問(wèn)題很容易,有很多種方法可以解決懊烤,比較經(jīng)典的方法有兩種梯醒,遞歸和動(dòng)態(tài)規(guī)劃。

動(dòng)態(tài)規(guī)劃

動(dòng)態(tài)規(guī)劃的思路是從最終態(tài)(第n月兔子的數(shù)量)開(kāi)始思考腌紧,嘗試找到第n個(gè)月兔子數(shù)量茸习,和第n-1個(gè)月兔子數(shù)量間的遞推關(guān)系。找到遞推關(guān)系之后壁肋,我們不需要在關(guān)注中間過(guò)程号胚,只需要從最初態(tài)開(kāi)始遞推籽慢,保存每次遞推的結(jié)果(每個(gè)月兔子的數(shù)量),自然就能得出第n個(gè)月兔子的數(shù)量猫胁。

從這道題來(lái)看箱亿,因?yàn)橥米邮且栽逻@個(gè)時(shí)間單位,一代一代生出來(lái)的弃秆,所以每個(gè)月的兔子數(shù)量届惋,應(yīng)該是存在遞推關(guān)系的。那么第n個(gè)月兔子數(shù)量應(yīng)該怎么和n-1個(gè)月兔子數(shù)量聯(lián)系起來(lái)呢菠赚?很顯然脑豹,因?yàn)橥米硬粫?huì)死亡,所以第n個(gè)月兔子的組成應(yīng)該是:n-1個(gè)月時(shí)全部的兔子衡查,和第n個(gè)月新生的兔子數(shù)量之和瘩欺。設(shè)第n個(gè)月的兔子數(shù)量為F(n),也就是:

F(n)=F(n-1)+第n月新生的兔子

為了完成這個(gè)狀態(tài)轉(zhuǎn)移方程拌牲,我們需要搞清第n月新生兔子和兔子數(shù)量之間的聯(lián)系俱饿。

我們不妨從第k月開(kāi)始跟蹤,因?yàn)橥米拥谌齻€(gè)月可以繁殖塌忽,也就是兔子其實(shí)可以劃分成三種不同的狀態(tài)拍埠,所以我們不妨用mature(k)表示第k月成熟的(可繁殖的)兔子數(shù)量,grow(k)表示第k月正在成長(zhǎng)的(在生命歷程第二個(gè)月的)兔子數(shù)量砚婆,最后用born(k)表示第k月新生的兔子數(shù)量:

k月時(shí)兔子的數(shù)量 ? ? ? ? ?? k+1月時(shí)兔子的數(shù)量 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? k+2月時(shí)兔子的數(shù)量

mature(k) ? ? ? ? ? ? ? ? ? ? ? mature(k+1)=mature(k)+grow(k) ? ? ? ? ?? mature(k+2)=mature(k+1)+grow(k+1)=mature(k)+grow(k)+born(k)

grow(k) ? ? ? ? ? ? ? ? ? ? ? ? ? grow(k+1)=born(k) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? grow(k+2)=born(k+1)=mature(k)+grow(k)

born(k)=mature(k) ? ? ? ?? born(k+1)=mature(k+1) ? ? ? ? ? ? ? ? ? ? ? ?? born(k+2)=mature(k+2)=mature(k)+grow(k)+born(k)

通過(guò)觀察這個(gè)遞推關(guān)系械拍,不難發(fā)現(xiàn)其實(shí)k+2個(gè)月時(shí)新生兔子的數(shù)量就等于第k月時(shí)兔子的總數(shù)。所以我們可以得到狀態(tài)轉(zhuǎn)移方程:

F(n)=F(n-1)+F(n-2)

其實(shí)也可以直觀的去想装盯,第n個(gè)月,所有兔子繁殖之前甲馋,總數(shù)就是n-1月兔子的總數(shù)F(n-1)埂奈,那么這F(n-1)對(duì)兔子中,又有多少是可繁殖的呢定躏,那想必需要減去其中不成熟的账磺,那實(shí)際上,兔子只會(huì)在自己新生的那個(gè)月和其下一個(gè)月不成熟痊远,也就是只需減去F(n-1)中新生的兔子數(shù)量垮抗,也就是:

第n月可以繁殖的兔子數(shù)量=F(n-1)-(n-1月新生的兔子)

結(jié)合我們已知的狀態(tài)轉(zhuǎn)移方程:F(n)=F(n-1)+第n月新生的兔子,將n-1帶入到方程的n中碧聪,顯然答案就是F(n-2)冒版,也就是第n月,可以繁殖的兔子數(shù)量就是F(n-2)逞姿,可以得到一樣的狀態(tài)轉(zhuǎn)移方程辞嗡。

C語(yǔ)言代碼實(shí)現(xiàn):

#include <stdio.h>

int main(){

? ? unsigned long count[100]={0};? //初始化數(shù)組保存兔子數(shù)量

????int n=0;

????printf("Please input month number(1~99):");

????scanf("%d",&n); //獲取用戶輸入的月份數(shù)

????for(int i=0;i<n;i++){

????????????????if(i==0||i==1){

????????????????????????????count[i]=1;

????????????????}

????????????????else{

????????????????????????????count[i]=count[i-1]+count[i-2];

? ? ? ? ? ? ?? }

????}

????printf("The number of rabbit is:%lu",count[n-1]);

}

這段代碼簡(jiǎn)單的實(shí)現(xiàn)了算法捆等,但是仍然需要升級(jí),因?yàn)殡m然用戶可輸入的范圍是1~99续室,但實(shí)際測(cè)試下栋烤,即使已經(jīng)使用了unsigned long,因?yàn)閡nsigned long的取值范圍為0至4,294,967,295挺狰,當(dāng)輸入月份在47以上的時(shí)候明郭,值會(huì)溢出》岵矗考慮下一步升級(jí)通過(guò)字符串?dāng)?shù)組保存兔子數(shù)量达址,實(shí)現(xiàn)大整數(shù)的保存。

遞歸

遞歸算法設(shè)計(jì)的思路上相對(duì)比較直接趁耗,明確終止條件沉唠,調(diào)用自身進(jìn)行運(yùn)算就可以了。

所以我們的終止條件是:

當(dāng)月份數(shù)減為1的時(shí)候 ?? return兔子數(shù)=1

當(dāng)月份數(shù)減為2的時(shí)候 ?? return兔子數(shù)=1

運(yùn)算過(guò)程:

F(n)=F(n-1)+F(n-2)

#include <stdio.h>

unsigned long recur(int n);

int main(){

????????int n=0;

????????scanf("%d",&n);

????????printf("%lu",recur(n));

????????return 0;

}

unsigned long recur(int n){

????????if(n==1||n==2){

????????????????return 1;

????????}

????????else{

????????????????return recur(n-1)+recur(n-2);

????????}

}

總結(jié)

兩種方法都可以完成這道題的計(jì)算苛败,但是實(shí)際運(yùn)行下來(lái)满葛,使用動(dòng)態(tài)規(guī)劃基本都是妙出結(jié)果(時(shí)間復(fù)雜度為O(n)),而遞歸則相對(duì)慢很多(時(shí)間復(fù)雜度O(2的n次方))罢屈,但從空間復(fù)雜度上來(lái)講嘀韧,遞歸更勝一籌。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末缠捌,一起剝皮案震驚了整個(gè)濱河市锄贷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌曼月,老刑警劉巖谊却,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異哑芹,居然都是意外死亡炎辨,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門聪姿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)碴萧,“玉大人,你說(shuō)我怎么就攤上這事末购∑朴鳎” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵盟榴,是天一觀的道長(zhǎng)曹质。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么咆繁? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任讳推,我火速辦了婚禮,結(jié)果婚禮上玩般,老公的妹妹穿的比我還像新娘银觅。我一直安慰自己,他們只是感情好坏为,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布究驴。 她就那樣靜靜地躺著,像睡著了一般匀伏。 火紅的嫁衣襯著肌膚如雪洒忧。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,198評(píng)論 1 299
  • 那天够颠,我揣著相機(jī)與錄音熙侍,去河邊找鬼。 笑死履磨,一個(gè)胖子當(dāng)著我的面吹牛蛉抓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剃诅,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼巷送,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了矛辕?” 一聲冷哼從身側(cè)響起笑跛,我...
    開(kāi)封第一講書(shū)人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎聊品,沒(méi)想到半個(gè)月后飞蹂,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡杨刨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年晤柄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妖胀。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惠勒,靈堂內(nèi)的尸體忽然破棺而出赚抡,到底是詐尸還是另有隱情,我是刑警寧澤纠屋,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布涂臣,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赁遗。R本人自食惡果不足惜署辉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望岩四。 院中可真熱鬧哭尝,春花似錦、人聲如沸剖煌。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)耕姊。三九已至桶唐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茉兰,已是汗流浹背尤泽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留规脸,地道東北人坯约。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像燃辖,于是被迫代替她去往敵國(guó)和親鬼店。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Java經(jīng)典問(wèn)題算法大全 /*【程序1】 題目:古典問(wèn)題:有一對(duì)兔子黔龟,從出生后第3個(gè)月起每個(gè)月都生一對(duì)兔子妇智,小兔子...
    趙宇_阿特奇閱讀 1,863評(píng)論 0 2
  • One 1 the [e?, ei:] art.這,那 ad.[用于比較級(jí)氏身;最高級(jí)前] 2 be [bi:,bi]...
    梁培林閱讀 9,287評(píng)論 0 10
  • 一巍棱、介紹 算法(Algorithm)是指解題方案的準(zhǔn)確而完整的描述,是一系列解決問(wèn)題的清晰指令蛋欣,算法代表著用系統(tǒng)的...
    走著別浪閱讀 554評(píng)論 0 3
  • 【0701晨讀】顧塵埃 今天分享的書(shū)籍是《別獨(dú)自用餐》 只有成為優(yōu)秀的人航徙,才會(huì)結(jié)識(shí)更多優(yōu)秀的人。 只從看到這句話之...
    顧塵埃閱讀 180評(píng)論 5 1
  • 1.來(lái)電 2.什么叫感應(yīng)起電陷虎? 原解釋如圖一到踏。 我開(kāi)腦洞的解釋: 1.AB一對(duì); 2.來(lái)個(gè)小三/男小三尚猿,A火熱窝稿;B...
    毛英勇閱讀 251評(píng)論 1 5