1. 程式人生 > >倍增算法

倍增算法

進行 nbsp 設定 tmp 了解 怎麽 文章 -- 介紹

  在上一篇求LCA的文章中,我們使用了倍增的算法(可以認為是二分思想的逆用),在這裏我們來簡單了解一下倍增算法的思想。

  有這樣一個問題,現在有一個數字n,現在要求將n分解為2的冪之和(n = ∑(20 + 21 + 22 + …… + 2i-1 + 2i)),要怎麽做?下面來介紹該怎麽辦,為了說明方便,我們假設n = 9 ,同時設定一個上限值16,也就是從24(令k = 4)開始分解:

  (1)9 < 24, 說明k太大了,將k = k - 1,此時n = 9,k = 3,

  (2)9 > 23,令9 - 23 = 1,繼續將k = k - 1,此時n = 1,k = 2,

  (3)1 < 22, 說明k太大了,繼續將k = k - 1,此時n = 1,k = 1,

  (4)1 < 21, 說明k太大了,繼續將k = k - 1,此時n = 1,k = 0,

  (5)1 = 20,令1 - 20 = 0,n分解完畢。

  總結上面的步驟,可以知道9 = 8 + 1 = 23 + 20 。將以上步驟一般化:,可以得到分解過程實際上就是一個在:預估一個k的上線,然後不斷地判斷n是否大於等於2k,如果是則n -= 2k,再對k--。以上步驟中有一點可以進行優化,對一個數進行位移操作,左位移就相當於乘以2,那麽我們可以對1左位移k位來表示2k這個數字。以上內容具體的實現代碼如下:

  

void doubly(int n)    //待分解的數
{
    int tmp = n;
        const int MAX = 20;    //冪的上限
    for(int i = 20; i >= 0; i--) 
    {
        if(tmp >= (1 << i))
        {
            tmp -= (1 << i);
        }
    }
}

倍增算法