一、描述
斐波那契数列(Fibonacci)是由1、1、2、3、5、8、13、21、34、55 ······ 构成的。
公式:
F
(
n
)
=
{
1
n=1、2
F
(
n
−
1
)
+
F
(
n
−
2
)
n>2
F(n)= \begin{cases} 1 & \text{n=1、2} \\ F(n-1)+F(n-2) & \text{n>2} \end{cases}
F(n)={1F(n−1)+F(n−2)n=1、2n>2
二、递归
#include<bits/stdc++.h>
using namespace std;
long long Fibonacci(int n){
if(n==1 || n==2){
return 1;
}
return Fibonacci(n-1) + Fibonacci(n-2);
}
int main()
{
int n;
cin>>n;
cout<<Fibonacci(n)<<endl;
return 0;
}
该方法的时间复杂度为 O ( 2 N ) O(2^N) O(2N),当 N N N非常大时,该方法将会运行超时。
三、动态规划
![](https://i-blog.csdnimg.cn/blog_migrate/c77dd63d85f7e730f18a121f9a019664.png)
由上图可知,许多数都会被重复计算,如果我们将前一次的计算结果保存起来就可以避免重复
动态规划的基本思想: 问题的最优解如果可以由子问题的最优解推导得到,则可以先求解子问题的最优解,在构造原问题的最优解;若子问题有较多的重复出现,则可以自底向上从最终子问题向原问题逐步求解。用空间换时间
#include<bits/stdc++.h>
using namespace std;
int main()
{
vector<long long> a;
int n;
cin>>n;
a.push_back(1);
a.push_back(1);
for(int i=2;i<n;i++){
a.push_back(a[i-1]+a[i-2]);
}
cout<<a[n-1]<<endl;
return 0;
}
该方法的时间复杂度为 O ( N ) O(N) O(N),空间复杂度也为 O ( N ) O(N) O(N)。
四、对空间进行优化
由公式可知我们可以只保留 F ( n ) F(n) F(n) 的前两个数,即: F ( n − 1 ) F(n-1) F(n−1) 和 F ( n − 2 ) F(n-2) F(n−2),不需要全部都保留。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
long long a,b,c;
a=1,b=1,c=1;
for(int i=2;i<n;i++){
c = a+b;
a=b;
b=c;
}
cout<<c<<endl;
}
该方法的时间复杂度为 O ( N ) O(N) O(N),空间复杂度为 O ( 1 ) O(1) O(1)。