斐波拉契数列、汉诺塔,青蛙跳台阶


 斐波拉契数列、汉诺塔,青蛙跳台阶  的算法实现

一.斐波那契数列 (1,1,2,3,5,8,13,21,34 ......)


f(n)=0,1,f(n1)+f(n2),n=0n=1n>2



  1. 递归解法(效率很低)
public function Fibonacci1($n)
{
  if($n <= 0){ return 0;}
  if($n == 1){ return 1; }
  return Fibonacci1($n - 1) + Fibonacci1($n - 2);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2 循环解法:改进的算法:从下往上计算。首先根据f(0)和f(1)算出f(2),再根据f(1)和f(2)算出f(3)。。。。。依此类推就可以算出第n项了。很容易理解,这种思路的时间复杂度是o(n)。实现代码如下:

public function Fibonacci($n)
{
    int $result[2] = {0 , 1};
    if($n < 2)
        return $result[$n];

    $one= 1;
    $tow= 0;
    for($i = 2 ; $i <= $n ; ++$i)
    {
        $fibN = $one+ $tow;

        $tow= $one;
        $one= $fibN;
    }

    return $fibN;
}
二.汉诺塔
简单的用php实现了汉诺塔问题的求解,使用递归调用,但是用php实现要是盘子的个数很多的话,运行起来会很慢的...
  汉诺塔主要是有三个塔座X,Y,Z,要求将三个大小不同,依小到大编号为1,2.....n的圆盘从A移动到塔座Z上,要求
  (1):每次只能移动一个圆盘
  (2):圆盘可以插到X,Y,Z中任一塔座上
  (3):任何时候不能将一个较大的圆盘压在较小的圆盘之上
  主要是运用了递归的思想,这里使用php做个简单的实现......
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
 
function hanoi($n,$x,$y,$z){
 
    if($n==1){
 
        move($x,1,$z);
 
    }else{
 
        hanoi($n-1,$x,$z,$y);
 
        move($x,$n,$z);
 
        hanoi($n-1,$y,$x,$z);
 
    }
 
}
 
function move($x,$n,$z){
 
    echo'movedisk'.$n.'from'.$x.'to'.$z.'<br>';
 
}
 
hanoi(10,'x','y','z');
 
?>

三.青蛙跳
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

与斐波那契数列不同的是,其初始值定义稍有不同, 
当n=1时,只能跳一级台阶,一种跳法 
当n=2时,一次跳一级或两级,两种跳法 
所以,关于青蛙跳台阶的定义如下:

假设n级台阶是f(n)的一个函数 ,当n = 1时候只有一种跳法,n=2时候 可以一次跳1台阶 ,也可以一次跳两个台阶 有两种跳法,但是当n>2时,第一次跳有两种不同的选择,选择跳一个台阶,那么就剩余f(n-1)种选择,如果第一次跳2台阶 接下来有f(n-2)种选择跳台阶,所以n级台阶的不同跳法f(n)=f(n-)+f(n-2)




f(n)=1,2,f(n1)+f(n2),n=1n=2n>2




  1. 非递归写法(借鉴)
long long FrogJump12Step(int n)
{
    if (n <= 0)
    {
        std::cerr << "param error" << std::endl;
        return -1;
    }

    if (n == 1)
        return 1;
    if (n == 2)
        return 2;
    int frogNMinusOne = 2;//f(n-1)=2
    int frogNMinusTwo = 1;//f(n-2)=1
    int frogN = 0;
    for (unsigned int i = 3; i <= n;++i)
    {
        frogN = frogNMinusOne + frogNMinusTwo;
        frogNMinusTwo = frogNMinusOne;
        frogNMinusOne = frogN;
    }
    return frogN;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  1. 递归解法(借鉴)
long long FrogJump12StepRecursive(int n)
{
    if (n <= 0)
    {
        std::cerr << "param error" << std::endl;
        return -1;
    }
    if (n == 1)
        return 1;
    if (n == 2)
        return 2;
    return FrogJump12StepRecursive(n - 1) + FrogJump12StepRecursive(n - 2);
}

四.青蛙跳升级版:
一只青蛙一次可以跳上1级台阶,也可以跳上2级......它也可以跳上n级,此时该青蛙跳上一个n级的台阶总共有多少种跳法?
按照上面的推理:

n = 1 时, 只有一种跳法  f(n) = 1;
n = 2 时 ,  有两种跳法,第一次跳一个台阶 ,第一次跳2台阶f(2) =  f(1) + f(0) = 2;
n = 3 时,f(n)= 3;第一次跳1个台阶,就剩余f(3-1) 跳法,第一次跳二台阶,就剩余f(3-2) ,第一次跳出3台阶,后面还有f(3-3) ,f(3) = f(2)+f(1)+f(0) = 4
......
n = n ,第一次共有n种跳法,第一次跳1台阶,后面还有f(n-1),第一次跳2,后面还有f(n-2),第一次跳3 ,后面还有f(n-3),。。。。。。,第一次跳n台阶,后面还有f(n-n)
    f(n) = f(n-1) + f(n-2) + f(n-3) + f(n-4) + ......+f(n-n);
 因为
  f(n-1) = f(n-2) + f(n-3) + f(n-4) + ......+f(n-n);
  => f(n) -f(n-1) = f(n-1)
 => f(n) = 2f(n-1)  n>2

f(n)=1,2,2f(n1),n=1n=2n>2

所以:f(n)=2f(n1)=22(n2)....=2n1f(0)=2n1


  1. 非递归解法:
public function FrogJump12nStep($n)
{
    if ($n <= 0)
    {
        return -1;
    }
    else if (n == 1)
        return 1;
    else
    {
        $fn1 = 1;
        $fn = 0;
        for ($i = 2; $i <= $n;++$i)
        {
            $fn = 2 * $fn1;
            $fn1 = $fn;
        }
        return $fn;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  1. 递归解法
public function  FrogJump12nStepRecursive($n)
{
    if ($n <= 0)
    {
        return -1;
    }
    else if ($n == 1)
        return 1;
    else if ($n == 2)
        return 2;
    else
        return 2 * FrogJump12nStepRecursive($n - 1);
}

     
 






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章