算法設(shè)計與分析 1.2 不一樣的fibonacci數(shù)列 (矩陣快速冪思想)

題目描述:

Winder 最近在學(xué)習(xí) fibonacci 數(shù)列的相關(guān)知識砸抛。我們都知道 fibonacci 數(shù)列的遞推公式是F(n) = F(n - 1) + F(n - 2)(n >= 2 且 n 為整數(shù))邀跃。

Winder 想知道的是當(dāng)我們將這個遞推式改為F(n) = a * F(n - 1) + b * F(n - 2)(n >= 2 且 n 為整數(shù))時我們得到的是怎樣的數(shù)列策添。但是,Winder 很懶定躏,所以只能由你來幫他來完成這件事患雇。

注意,這里我們依然令 F(0)=F(1)=1胞得。

輸入格式:

輸入第一行三個正整數(shù) q, a, b。

接下來有 q 行屹电,每行一個自然數(shù) n阶剑。

對于50%的數(shù)據(jù),1 <= q危号、n <= 1000牧愁。

對于80%的數(shù)據(jù),1 <= q葱色、n <= 100000递宅。

對于100%的數(shù)據(jù),1 <= q <= 100000,1 <= n <= 1000000000,1 <= a苍狰、b <= 1000办龄。

輸出格式

輸出一行一個整數(shù) F(n),由于結(jié)果可能會很大淋昭,Winder 要求輸出結(jié)果對 2013 取模俐填,即將 F(n)對2013求余后輸出。

樣例輸入

5 4 5
2
4
8
16
32

樣例輸出

9
209
1377
182
9

方法一:

剛開始拿到題目的時候第一反應(yīng)是按要求做一個遞歸算法翔忽,但是后來發(fā)現(xiàn)遞歸的代價太大英融,可能會過不了。

方法二:

和方法一一個思路歇式,但是使用了非遞歸算法驶悟,雖然肯定不是最優(yōu)算法,但是應(yīng)該可以得一個基礎(chǔ)分了材失。

#include <iostream>
using namespace std;
int fibonacci(int n, int a, int b)
{
       if (n <= 1)
              return 1;
       else
       {
              int current = 0;
              int pre1 = 1;
              int pre2 = 1;
              for (int i = 2; i <= n; i++)
              {
                     current = (a * pre1 + b * pre2) % 2013;
                     pre2 = pre1;
                     pre1 = current;
              }
              return current;
       }
}
int main()
{
       int q, a, b;
       cin >> q >> a >> b;
       int *result = new int[q];
       for (int i = 0; i < q; i++) {
              int n;
              cin >> n;
              result[i] = fibonacci(n, a, b);
       }
       for (int i = 0; i < q; i++) {
              cout << result[i] << endl;
       }
       delete[]result;
       return 0;
}

方法三:

這個是在理解了矩陣快速冪的思想基礎(chǔ)上痕鳍,進行改進的一個算法,把問題規(guī)模直接降了一大截。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
const int MOD = 2013;
 
struct matrix {     //矩陣 
    int m[2][2];
}ans;
 
matrix multi(matrix a, matrix b) {  //矩陣相乘笼呆,返回一個矩陣 
    matrix tmp;
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            tmp.m[i][j] = 0;
            for (int k = 0; k < 2; k++)
                tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % MOD;
        }
    }
    return tmp;
}
 
matrix matrix_pow(matrix a, int n) {   //矩陣快速冪熊响,矩陣a的n次冪 
    ans.m[0][0] = ans.m[1][1] = 1;  //初始化為單位矩陣 
    ans.m[0][1] = ans.m[1][0] = 0;
    while (n) {
        if (n & 1) ans = multi(ans, a);
        a = multi(a, a);
        n >>= 1;
    }
    return ans;
}
 
int main() {
    int q, n, a, b;
    cin >> q >> a >> b;
    int* result = new int[q];
    matrix mul;
    mul.m[0][0] = a;
    mul.m[0][1] = b;
    mul.m[1][0] = 1;
    mul.m[1][1] = 0;
    for (int i = 0; i < q; i++) {
        int n;
        cin >> n;
        matrix mm = matrix_pow(mul, n - 1);
        result[i] = (mm.m[0][0] + mm.m[0][1])%MOD;
    }
    for (int i = 0; i < q; i++) {
        cout << result[i] << endl;
    }
    delete[]result;
    return 0;
}

第一次做的時候因為最后一步的時候在result[i] = (mm.m[0][0] + mm.m[0][1])%MOD的時候忘記了加這個“%MOD”,導(dǎo)致結(jié)果一直有部分不對诗赌,調(diào)試了將近一個上午汗茄。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市铭若,隨后出現(xiàn)的幾起案子洪碳,更是在濱河造成了極大的恐慌,老刑警劉巖奥喻,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件偶宫,死亡現(xiàn)場離奇詭異,居然都是意外死亡环鲤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門憎兽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冷离,“玉大人,你說我怎么就攤上這事纯命∥靼” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵亿汞,是天一觀的道長瞭空。 經(jīng)常有香客問我,道長疗我,這世上最難降的妖魔是什么咆畏? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮吴裤,結(jié)果婚禮上旧找,老公的妹妹穿的比我還像新娘。我一直安慰自己麦牺,他們只是感情好钮蛛,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著剖膳,像睡著了一般魏颓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吱晒,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天甸饱,我揣著相機與錄音,去河邊找鬼枕荞。 笑死柜候,一個胖子當(dāng)著我的面吹牛搞动,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播渣刷,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼鹦肿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辅柴?” 一聲冷哼從身側(cè)響起箩溃,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎碌嘀,沒想到半個月后涣旨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡股冗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年霹陡,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片止状。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡烹棉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出怯疤,到底是詐尸還是另有隱情浆洗,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布集峦,位于F島的核電站伏社,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏塔淤。R本人自食惡果不足惜摘昌,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凯沪。 院中可真熱鬧第焰,春花似錦、人聲如沸妨马。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烘跺。三九已至湘纵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間滤淳,已是汗流浹背梧喷。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铺敌。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓汇歹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親偿凭。 傳聞我的和親對象是個殘疾皇子产弹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345