斐波那契系列问题的递归和动态规划

给定整数N,返回斐波那契数列的第N项

方法一:暴力递归 O(n^2)

#coding=utf-8
import sys

def solution(n):
    if n<1:
        return 0
    if n==1 or n==2:
        return 1
    return solution(n-2)+solution(n-1)

while True:
    try:
        N=input()
        print solution(N)
    except:
        break

方法二:
从左到右依次求出每一项的值 O(n)

def solution(n):
    if n<1:
        return 0
    if n==1 or n==2:
        return 1
    res=1
    pre=1
    tmp=0
    for i in range(3,n+1):
        tmp=res
        res=res+pre
        pre=tmp
    return res

方法三:
平方递归,使用矩阵

def muliMatrix(m1,m2):
    res=[]
    for i in range(len(m1)):
        res.append([])
        for j in range(len(m2[0])):
            res[i].append(0)
            for k in range(len(m2)):
                res[i][j]+=m1[i][k]*m2[k][j]
    return res

def matrixPower(m,p):
    #res=[[1 for _ in range(len(m[0]))] for i in range(len(m))]
    res=m
    tmp=m
    while p!=0:
        if p&1==1:
            res=muliMatrix(res,tmp)
        tmp=muliMatrix(tmp,tmp)
        p=p>>1
    return res


def solution(n):
    if n<1:
        return 0
    if n==1 or n==2:
        return 1
    base=[[1,1],[1,0]]
    res=matrixPower(base,n-3)
    return res[0][0]+res[1][0]

说明一下muliMatrix函数是矩阵相乘,matrixPower是计算矩阵的几次方,因为初始是[[Fn+1,Fn],[Fn,Fn-1]]==[[1,1],[1,0]],要计算矩阵的m次方,只需要算到m-2次方就可以了,因为Fn==Fn-1+Fn-2,所以只需要算[[Fn-1,Fn-2],[Fn-2,Fn-3]]这个矩阵就可以了。在这里将矩阵初始为base矩阵,所以只需要算n-3次方,比如求3,[[F2,F1],[F1,F0]]已经是base矩阵的一次方了。

说明一下下面的代码

while p!=0:
    if p&1==1:
        res=muliMatrix(res,tmp)
    tmp=muliMatrix(tmp,tmp)
    p=p>>1

&是按位与运算,这里是看p当前最右边的一位是否是1,如果是1,说明要乘上base的当前次方,tmp就是几次方的base矩阵。
比如说,需要5次方,p就是101,最右一位是1,所以乘tmp的一次方,然后tmp变成tmp^2,p变成10,最右是0,不用乘,tmp变成tmp^4,p变为1,res乘tmp^4。

给定整数N,代表台阶数,一次可以跨2个或者1个台阶,返回有多少种走法

方法一: 暴力递归

#coding=utf-8

def solution(N):
    global res
    if N<0:
        return
    if N==0:
        res+=1
        return
    solution(N-1)
    solution(N-2)

while True:
    try:
        N=input()
        res=0
        solution(N)
        print res
    except:
        break

方法二: 如果台阶有N级,最后跳上N级的情况,要么是从N-2级台阶直接跨2级台阶,要么是从N-1级台阶跨1级台阶,所有S(N)=S(N-2)+S(N-1),所以可以用斐波那契数列的三种方法,参考上面

生小牛问题

假设农场中成熟的母牛每年只会生1头小母牛,并且永远不会死。第一年农场有1只成熟的母牛,从第二年开始,母牛将开始生小母牛。每只小母牛3年之后成熟又可以开始生小母牛。给定整数N,求出N年后牛的数量。
自己的思路
年数 成熟的牛 总牛
1 1 1
2 1 2
3 1 3
4 1 4
5 2 6
6 3 9
7 4 13
8 6 19
成熟的牛f(n)=f(n-1)+f(n-3) 总牛g(n)=g(n-1)+f(n)
书上的思路
第N-1年的牛会毫无损失的活到第N年,同时所有成熟的牛都会生1头新的牛,第N年成熟牛的数量就是第N-3年总牛的数量。所以C(n)=C(n-1)+C(n-3),初始项C(1)==1,C(2)==2,C(3)==3。其实自己的思路里的f(n)==g(n-3)
解法
这个题在用矩阵的时候,是三阶矩阵
(Cn,Cn-1,Cn-2)=(Cn-1,Cn-2,Cn-3)*状态矩阵
所以状态矩阵
| 1 1 0 |
| 0 0 1 |
| 1 0 0 |

参考:程序员代码面试指南:IT名企算法与数据结构题目最优解 左神的书

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值