赞
踩
版权声明:本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址
http://blog.csdn.net/lzuacm。
斐波那契(Fibonacci)数列,除了可以用跟递归方法来处理,还可以使用动态规划方法(DP)来求解。区别在于,如果使用动态规划方法,中间结果要“缓存”起来,以备后续使用,这样时间复杂度即优化为O(N)。动态规划的具体做法就是将每次调用fibonacci(i)的结果“缓存”起来。
在普通电脑上,递归版本生成第50项斐波那契数用时可能超过一分钟,而动态规划方法只需几毫秒就能产生第10000项斐波那契数。当然,若采用int型变量,很快就会溢出,需要改为long long类型。
事实上,DP = “careful” Brute force = Sub-problem + reuse
Technique: memorization (记忆化,缓存)
伪代码(Memorized DP algorithm - pseudocode):
memo = {}
fib(n):
if n in memo: return memo[n]
if n<= 2: f = 1
else: f = fib(n-1) + fib(n-2)
memo[n] = f
return f
子问题划分图示:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define N 200000000
long long num[N+1]; // 全局变量,初始化为0
long long fib(unsigned i)
{
if (i <= 1)
return i;
if(num[i] != 0)
return num[i]; // 不为0时表明数据有更新, 返回先前缓存的结果
num[i] = fib(i-1) + fib(i-2); // 缓存结果
return num[i];
}
int main()
{
int m;
while(cin>>m) // in: 1499 out: 6688774161928657529
{
cout<<fib(m)<<endl;
// memset(num, 0, sizeof(num));
}
return 0;
}
事实上,对于10000位或以上位数,需使用BigInteger来存储。而C++官方自带库并无BigInteger类,下面用笔者较熟悉的C#和Java中的BigInteger类来实现一下~
用C#的BigInteger类实现的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
namespace Fibonacci_Large
{
public class Solution
{
public static void Fib(int n)
{
List<BigInteger> fibonacci = new List<BigInteger>();
fibonacci.Add(0);
fibonacci.Add(1);
BigInteger i = 2;
while (i < n)
{
int first = (int)i - 2;
int second = (int)i - 1;
BigInteger firstNumber = fibonacci[first];
BigInteger secondNumber = fibonacci[second];
BigInteger sum = firstNumber + secondNumber;
fibonacci.Add(sum);
i++;
}
Console.WriteLine(fibonacci.LastOrDefault());
}
public static void Main(String[] args)
{
int n = 100000;
Fibonacci.Fib(n);
}
}
}
ps: 记得在项目的Reference中加入System.Numerics库,加入成功后才能使用BigInteger~
而用Java的BigInteger则可实现如下:
import java.io.*;
import java.util.*;
import java.math.*;
public class Fibonacci
{
// Returns n-th Fibonacci number
static BigInteger fib(int n)
{
BigInteger a = BigInteger.valueOf(0);
BigInteger b = BigInteger.valueOf(1);
BigInteger c = BigInteger.valueOf(1);
for (int j=2 ; j<=n ; j++)
{
c = a.add(b);
a = b;
b = c;
}
return (a);
}
public static void main(String[] args)
{
int n = 100000;
System.out.println("Fibonacci of " + n +
"th term" + " " +"is" +" " + fib(n));
}
}
相关参考:
http://blog.csdn.net/lzuacm/article/details/51164970
Crackling the Code Interview - chapter 9
动态规划概论 | Fogsail
http://www.fogsail.net/2017/02/02/20170202/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。