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

来源:互联网 发布:微软程序员工资 编辑:程序博客网 时间:2024/06/07 14:55

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

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

#coding=utf-8import sysdef 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 resdef 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 resdef 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-8def 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名企算法与数据结构题目最优解 左神的书

原创粉丝点击