• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            雁過(guò)無(wú)痕

            《編程之美》讀書(shū)筆記08:2.9 Fibonacci序列

            計(jì)算Fibonacci序列最直接的方法就是利用遞推公式 F(n+2)=F(n+1)+F(n)。而用通項(xiàng)公式來(lái)求解是錯(cuò)誤的,用浮點(diǎn)數(shù)表示無(wú)理數(shù)本來(lái)就有誤差,經(jīng)過(guò)n次方后,當(dāng)n相當(dāng)大時(shí),誤差能足夠大到影響浮點(diǎn)數(shù)轉(zhuǎn)為整數(shù)時(shí)的精度,得到的結(jié)果根本不準(zhǔn)。

            用矩陣來(lái)計(jì)算,雖然時(shí)間復(fù)雜度降到O(log n),但要用到矩陣類(lèi),相當(dāng)麻煩。觀察:

            F(n+2)=F(n)+F(n-1)2*F(n-1)+F(n-2)=3*F(n-2)+2*F(n-4)

            用歸納法很容易證明 F(n) = F(k)*F(n+1-k) + F(k-1)*F(n-k),利用該遞推公式和原遞推公式,要計(jì)算F(n),只要計(jì)算F([n/2])F([n/2]+1),時(shí)間復(fù)雜度為 O(lg n)。如:要計(jì)算F(58),由 58 -> 29,30 -> 14,15 -> 7,8 -> 3,4 -> 1,2 可知只要算5次。可以用一個(gè)棧保存要計(jì)算的數(shù),實(shí)際上,將n的最高位1(假設(shè)在第k位)左邊的0去除掉后,第m次要計(jì)算的數(shù)是第k位到第k-m+1位這m個(gè)位組成的值t(m),則第m-1次要計(jì)算的數(shù)為t(m-1),且

            t(m)=2*t(m-1)+(k-m+1位是否為1)。

            若第m-1次計(jì)算得到了f(k)f(k+1),則第m次計(jì)算:

             

            k-m+1

            已計(jì)算

            待計(jì)算

            1

            f(k)

            f(k+1)

            f(2*k+1),f(2*k+2)

            0

            f(2*k),f(2*k+1)

             

            具體公式見(jiàn)下面代碼。

            下面是計(jì)算F(n)最后四位數(shù)(某道ACM題)的代碼。


             

            /*   Fibonacci數(shù)列第N個(gè)數(shù)的最后4位數(shù)
                注意,當(dāng) N>93 時(shí) 第N個(gè)數(shù)的值超過(guò)64位無(wú)符號(hào)整數(shù)可表示的范圍。
            F(n+2)=F(n)+F(n-1) F(0)=0 F(1)=1  F(2)=1        ==>
            F(n)=F(k)*F(n+1-k) + F(k-1)*F(n-k)              ==>
            F(2*n)=F(n+1)*F(n)+F(n)*F(n-1)=(F(n+1)+F(n-1))*F(n)=(F(n+1)*2-F(n))*F(n)
            F(2*n+1)=F(n+1)*F(n+1)+F(n)*F(n)
            F(2*n+2)=F(n+2)*F(n+1)+F(n+1)*F(n)=(F(n+2)+F(n))*F(n+1)=(F(n+1)+F(n)*2)*F(n+1)
             
            */

            unsigned fib_last4( unsigned num)
            {
              
            if ( num == 0 ) return 0;
              
            const unsigned M=10000;
              unsigned ret
            =1,next=1,ret_=ret;
              unsigned flag
            =1, tt=num;
              
            while ( tt >>= 1) flag <<= 1;
              
            while ( flag >>= 1 ){
                
            if ( num & flag ){
                  ret_ 
            = ret * ret + next * next;
                  next 
            = (ret + ret + next) * next;
                } 
            else {
                  
            //多加一個(gè)M,避免 2*next-ret是負(fù)數(shù),造成結(jié)果不對(duì)
                  ret_ = (next + next + M - ret) * ret;
                  next 
            = ret * ret + next * next;
                }
                ret 
            = ret_ % M;
                next 
            = next % M;
              }
              
            return ret;
            }


             



            posted on 2010-06-23 23:28 flyinghearts 閱讀(4723) 評(píng)論(11)  編輯 收藏 引用 所屬分類(lèi): 算法編程之美

            評(píng)論

            # re: O(log n)求Fibonacci數(shù)列(非矩陣法)[未登錄](méi) 2010-07-16 11:18 Klion
            你好,這篇文章下面這段文字“實(shí)際上,將n的最高位1(假設(shè)在第k位)左邊的0去除掉后,第m次要計(jì)算的數(shù)是第k位到第k-m+1位這m個(gè)位組成的值t(m),則第m-1次要計(jì)算的數(shù)為t(m-1),且t(m)=2*t(m-1)+(第k-m+1位是否為1)。若第m-1次計(jì)算得到了f(k)和f(k+1),則第m次計(jì)算:”
            不是看的很懂,希望博主給解釋下。
            主要有以下幾點(diǎn)疑問(wèn):1.那個(gè)最高位左邊的是比最高位高的位還是低的位。
            2.那個(gè)t(m)怎么算的  回復(fù)  更多評(píng)論
              

            # re: O(log n)求Fibonacci數(shù)列(非矩陣法) 2010-07-18 05:16 dissertation service
            A lot of years good people would like to order good enough history dissertation referring to this good post from the dissertation writing services. Can you in case suggest the experienced thesis writing services? Thanks a lot.   回復(fù)  更多評(píng)論
              

            # re: O(log n)求Fibonacci數(shù)列(非矩陣法) 2010-07-21 00:35 flyinghearts
            @Klion

            以58為例其二進(jìn)制表示(最左邊的0省略)為:
              11 1010
            t(1) 1
            t(2) 11
            t(3) 11 1
            t(4) 11 10
            t(5) 11 101
            t(6) 11 1010

            即:
            t(1)?。健?
            t(2)?。健?
            t(3) = 7
            t(4) = 14
            t(5)?。健?9
            t(6)?。健?8

              回復(fù)  更多評(píng)論
              

            # re: O(log n)求Fibonacci數(shù)列(非矩陣法)[未登錄](méi) 2010-07-26 11:40 Klion
            @flyinghearts
            恩,謝謝了。后來(lái)我自己也動(dòng)手劃了下,原來(lái)我一開(kāi)始沒(méi)理解到,現(xiàn)在我知道那個(gè)t(m)怎么算的,也用自己的理解寫(xiě)了點(diǎn)求出這個(gè)是干嘛的。
            我理解的就是這個(gè)t(m)其實(shí)就是一個(gè)逆向工程,先是判斷右移(m-1)位之后的情況,看這個(gè)數(shù)是奇數(shù)還是偶數(shù),如果是奇數(shù)就由哪兩個(gè)數(shù)得來(lái),如果是偶數(shù),就由哪兩個(gè)數(shù)得來(lái),由這個(gè)可以得到我們要算的結(jié)果是算出來(lái)的這兩個(gè)中的小者。  回復(fù)  更多評(píng)論
              

            # re: O(log n)求Fibonacci數(shù)列(非矩陣法) 2010-08-02 23:34 flyinghearts
            @Klion
            58 -> 29 -> 14 -> 7 -> 3 -> 1
            t(i)就是這個(gè)倒過(guò)來(lái)。
            要計(jì)算 F(t(i)) 就要判斷 t(i) 是 t(i-1)的2倍,還是2倍加1
            (實(shí)際上,t(i)沒(méi)必要計(jì)算,只要判斷第k-m+1位是否為1就可以了。)
            根據(jù)這兩個(gè)情況,決定使用那幾個(gè)公式。


            我最初的代碼,就是用一個(gè)棧,保存n每次右移1位的結(jié)果,
            最后根據(jù)棧頂是否是奇數(shù),來(lái)決定調(diào)用那兩個(gè)公式,出棧。
            反復(fù)至棧為空。



              回復(fù)  更多評(píng)論
              

            # re: 《編程之美》讀書(shū)筆記08:2.9 Fibonacci序列 —— O(log n)求Fibonacci數(shù)列(非矩陣法)[未登錄](méi) 2010-10-06 05:47 april
            謝謝帖主的分享,不過(guò)code算出來(lái)的結(jié)果是錯(cuò)的,貼主有測(cè)試過(guò)嗎?
            遞推公式 F(n+2)=F(n)+F(n-1) 是錯(cuò)的
            正確的是 F(n+1)=F(n)+F(n-1), 我想這是為什么算出來(lái)的結(jié)果不是F(n), 而是F(n-1).
              回復(fù)  更多評(píng)論
              

            # re: 《編程之美》讀書(shū)筆記08:2.9 Fibonacci序列 —— O(log n)求Fibonacci數(shù)列(非矩陣法)[未登錄](méi) 2010-10-06 06:01 april
            @april
            收回我的評(píng)論,雖然遞推公式寫(xiě)錯(cuò)(typo),但是code返回結(jié)果正確。。  回復(fù)  更多評(píng)論
              

            # re: 《編程之美》讀書(shū)筆記08:2.9 Fibonacci序列 —— O(log n)求Fibonacci數(shù)列(非矩陣法) 2010-12-02 23:34 flyinghearts
            @april
            確實(shí)把公式打錯(cuò)了:
            F(n+2)=F(n)+F(n-1) 應(yīng)該是 F(n+1) = F(n) + F(n-1)
            不過(guò)后面的公式推導(dǎo)沒(méi)問(wèn)題。

              回復(fù)  更多評(píng)論
              

            # re: 《編程之美》讀書(shū)筆記08:2.9 Fibonacci序列 —— O(log n)求Fibonacci數(shù)列(非矩陣法) 2012-09-03 10:26
            不過(guò)實(shí)測(cè)的結(jié)果:是matrix版(O(logn))最快,去遞歸的(bottom-up)版(O(n))次之,然后是這個(gè)版本(O(logn)),可能是乘法的緣故  回復(fù)  更多評(píng)論
              

            # re: 《編程之美》讀書(shū)筆記08:2.9 Fibonacci序列 —— O(log n)求Fibonacci數(shù)列(非矩陣法) 2013-04-26 23:21 card323
            我寫(xiě)了一篇文章 ggboom.com/2013/04/26/ologn%E6%B1%82%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91fibonacci%E6%95%B0%E5%88%97/
            歡迎拍磚  回復(fù)  更多評(píng)論
              

            # re: 《編程之美》讀書(shū)筆記08:2.9 Fibonacci序列 —— O(log n)求Fibonacci數(shù)列(非矩陣法) 2013-04-26 23:23 card323
            @黃
            試試我的算法:
            ggboom.com/2013/04/26/ologn%E6%B1%82%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91fibonacci%E6%95%B0%E5%88%97/  回復(fù)  更多評(píng)論
              

            久久精品国产WWW456C0M| 国产亚洲欧美精品久久久| 少妇无套内谢久久久久| 无码久久精品国产亚洲Av影片| 国产午夜免费高清久久影院| 久久国产精品二国产精品| 亚洲综合日韩久久成人AV| 999久久久免费国产精品播放| 一本色道久久综合狠狠躁篇| 久久久国产精品网站| 亚洲精品无码久久久久去q| 久久精品国产只有精品66| 精品久久久久久无码中文字幕一区| 久久久久国产一区二区| 精品精品国产自在久久高清| 久久久噜噜噜久久中文字幕色伊伊 | 中文字幕一区二区三区久久网站| 久久亚洲av无码精品浪潮| 国产精品久久影院| 亚洲午夜久久久久久久久久| 久久久久亚洲AV成人网人人软件| 久久精品人人槡人妻人人玩AV | 欧美日韩久久中文字幕| 久久99精品国产麻豆不卡| 国产99精品久久| 亚洲日韩中文无码久久| 尹人香蕉久久99天天拍| 久久久久无码精品| Xx性欧美肥妇精品久久久久久| 丰满少妇高潮惨叫久久久| 久久亚洲精品国产精品| 亚洲精品乱码久久久久久自慰| 久久久久se色偷偷亚洲精品av| 一本色道久久综合| 久久免费看黄a级毛片| 伊人久久综合无码成人网| 亚洲色欲久久久综合网东京热| 狠狠综合久久AV一区二区三区| 久久天天躁狠狠躁夜夜avapp| 日韩欧美亚洲综合久久| 欧美日韩精品久久免费|