算法时间复杂度lg是多少_斐波那契数的 O(lgn) 时间复杂度算法 | 学步园

看了

This problem compares the efficiency of three methods for computing the nth Fibonacci number Fn, given n. Assume that the cost of adding, subtracting, or multiplying two numbers is O(1), independent of the size of the numbers.

Show that the running time of the straightforward recursive method for computing Fn based on recurrence (3.21) is exponential in n.

Show how to compute Fn in O(n) time using memoization.

Show how to compute Fn in O(lg n) time using only integer addition and multiplication. (Hint: Consider the matrix

0    1

1    1

and its powers.)

Assume now that adding two β-bit numbers takes Θ(β) time and that multiplying two β-bit numbers takes Θ(β2) time. What is the running time of these three methods under this more reasonable cost measure for the elementary arithmetic operations?

使用第三种算法,计算 矩阵0    1

FibMat =

1     1

的 p 次幂(反复平方法),右下角的元素即为 Fp (假设数列从下标 0 开始)。

//第 n 个 Fibinacci 数的 O(lgn) 时间复杂度的求法#includeusingnamespacestd;

templatestructFibMat

{

    T f00;

    T f01;

    T f10;

    T f11;

    FibMat (T a=0, T b=1, T c=1, T d=1);

voidprint ();

};

templateFibMat::FibMat(T a, T b, T c, T d)

{

    f00=a;

    f01=b;

    f10=c;

    f11=d;

}

templatevoidFibMat::print ()

{

    cout<

    cout<

}

templateFibMatFibMat_Mul (FibMat&a, FibMat&b)

{

    T f00=a.f00*b.f00+a.f01*b.f10;

    T f01=a.f00*b.f01+a.f01*b.f11;

    T f10=a.f10*b.f00+a.f11*b.f10;

    T f11=a.f10*b.f01+a.f11*b.f11;

returnFibMat(f00, f01, f10, f11);

}

templateT FibCounter (intp)

{

    FibMatfm (0,1,1,1);//计算 fm 的 p 次幂,返回右下角的元素FibMatfm_pow (0,1,1,1);

intj=1;

while(j<=p)

...{

        j<<=1;

        }    j>>=1;//j 是不超过 p 的 2 幂while(j>>=1)

...{

        fm_pow=FibMat_Mul (fm_pow, fm_pow);

if(j&p)

...{

            fm_pow=FibMat_Mul (fm_pow, fm);

            }        }returnfm_pow.f11;

}

intmain ()

{

inti;

for(i=1; i<91; i++)

...{

        cout<(i)<

        }return0;

}..................

运行结果:

1

2

3

5

8

13

21

34

55

89

144

233

377

610

987

1597

2584

4181

6765

10946

17711

28657

46368

75025

121393

196418

317811

514229

832040

1346269

2178309

3524578

5702887

9227465

14930352

24157817

39088169

63245986

102334155

165580141

267914296

433494437

701408733

1134903170

1836311903

2971215073

4807526976

7778742049

12586269025

20365011074

32951280099

53316291173

86267571272

139583862445

225851433717

365435296162

591286729879

956722026041

1548008755920

2504730781961

4052739537881

6557470319842

10610209857723

17167680177565

27777890035288

44945570212853

72723460248141

117669030460994

190392490709135

308061521170129

498454011879264

806515533049393

1304969544928657

2111485077978050

3416454622906707

5527939700884757

8944394323791464

14472334024676221

23416728348467685

37889062373143906

61305790721611591

99194853094755497

160500643816367088

259695496911122585

420196140727489673

679891637638612258

1100087778366101931

1779979416004714189

2880067194370816120

4660046610375530309

再接着算就超过 64 位有符号数的范围了。可以考虑用自定义的超长整数类来算。前几天我就花了 3 天时间来写了一个超长整数类,加减乘除的方法都写好了,速度不必 JAVA 的慢。HOHO~~有空会 post 出来开源o(∩_∩)o...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值