算法导论 31-3 关于斐波那契数的三个算法

来源:互联网 发布:淘宝认证在哪里 编辑:程序博客网 时间:2024/06/05 21:14

31-3(关于斐波那契数的三个算法) 在已知n的情况下,本题对计算第n个斐波那契数Fn的三种算法的效率进行了比较。假定两个数的加法,减法和乘法的代价都是O(1),与数的大小无关。

a.证明:基于递归式(3.22)计算Fn的直接递归方法的运行时间为n的幂。

b.试说明如何运用记忆法在O(n)时间内计算Fn.

c.试说明如何仅用整数加法和乘法运算,就可以在O(lgn)的时间内计算Fn.(提示:考虑2x2矩阵[0,1,1,1]和它的幂。)

3.22: Fibonacci numbers

We define the Fibonacci numbers by the following recurrence:

F(0) = 0, F(1) = 1, F(i) = F(i-1) + F(i-2) for (i>=2).

/* 31-3 Three algorithms for Fibonacci numbers 3.223.22: Fibonacci numbersWe define the Fibonacci numbers by the following recurrence:F(0) = 0, F(1) = 1, F(i) = F(i-1) + F(i-2) for (i>=2). */public class FibonacciNumbers {  public static void main(String[] args) {    for(int i=0; i< 20; i++) {      System.out.println("fibona("+i+")="+fibona1(i));    }    for(int i=0; i< 20; i++) {      System.out.println("fibona("+i+")="+fibonaByMatrixPower(i+1).getFibonaNb());    }    for(int i=0; i< 20; i++) {      System.out.println("fibona("+i+")="+fibona2(i));    }  }  // b. Show how to compute F(n) in O(n) time using memoization O(n) space.  public static int fibona2(int n) {    if(n<0) throw new IllegalArgumentException("Fibonacci(n), n>=0");    if(n == 0 || n == 1) {      return n;    }    int[] result = new int[n+1];    result[0] = 0;    result[1] = 1;    for(int i=2; i<=n; i++) {      result[i] = result[i-1] + result[i-2];    }    return result[n];  }  // b. Show how to compute F(n) in O(n) time using O(1) space.  public static int fibona1(int n) {    if(n<0) throw new IllegalArgumentException("Fibonacci(n), n>=0");    if(n==0) return 0;  // f(0) = 0;    if(n==1) return 1;    if(n==2) return 1;    int fn_1 = 1;    int fn_2 = 1;    int fn = 0;    for(int i=3; i<=n; i++) {      fn = fn_1 + fn_2;      fn_2 = fn_1;      fn_1 = fn;    }    return fn;  }  // c. Show how to compute Fn in O(lgn) time using only integer addition and multiplication.  // (Hint: Consider the matrix (0,1) and and its powers.) matrix[0][0] if fibona number  //                            (1,1)  // f(0)=a.00, f(1)=(a^2).00, f(n)=(a^(n+1)).00  public static FibonaMatrix fibonaByMatrixPower(int n) {    if(n<1) throw new IllegalArgumentException("Fibona(n) by matrix power, n>=1");    if (n == 1) {      return FibonaMatrix.getFibonaMatrix();    }    FibonaMatrix fibHalf = fibonaByMatrixPower(n>>1);    FibonaMatrix fib = FibonaMatrix.multiply(fibHalf, fibHalf);    if((n & 1) == 1) {      fib = FibonaMatrix.multiply(fib, FibonaMatrix.getFibonaMatrix());    }    return fib;  }  //F(n)为[0,1,1,1]^n+1的[0][0],这个可用数学归纳法证明, f(n)=(a^(n+1)).[0][0],   static class FibonaMatrix {    final private int[][] matrix = new int[2][2];    private FibonaMatrix() {      matrix[0][0] = 0;      matrix[0][1] = 1;      matrix[1][0] = 1;      matrix[1][1] = 1;    }    public static FibonaMatrix multiply(FibonaMatrix one, FibonaMatrix another) {      FibonaMatrix ret = getFibonaMatrix();      ret.matrix[0][0] = one.matrix[0][0] * another.matrix[0][0] + one.matrix[0][1]*another.matrix[1][0];      ret.matrix[0][1] = one.matrix[0][0] * another.matrix[0][1] + one.matrix[0][1]*another.matrix[1][1];      ret.matrix[1][0] = one.matrix[1][0] * another.matrix[0][0] + one.matrix[1][1]*another.matrix[1][0];      ret.matrix[1][1] = one.matrix[1][0] * another.matrix[0][1] + one.matrix[1][1]*another.matrix[1][1];      return ret;    }    public int getFibonaNb() {      return matrix[0][0];    }    public static FibonaMatrix getFibonaMatrix() {      return new FibonaMatrix();    }  }}



0 0
原创粉丝点击