斐波那契数列(动态规划)
斐波那契数列是一个经典的数列问题,其定义如下:
- F(0)=1
- F(1)=1
- 对于 n≥2,F(n)=F(n−1)+F(n−2)
斐波那契数列广泛应用于算法设计和数学问题中。使用动态规划可以有效地计算斐波那契数列。以下是详细的算法实现,包括原理、步骤、图示法表示步骤、代码关键行注释和时间复杂度。
1. 算法原理
动态规划的核心思想是将问题分解为更小的子问题,并存储子问题的结果以避免重复计算。具体步骤如下:
定义子问题:
- 设dp[i] 表示斐波那契数列的第 ii 项。
递推关系:
- dp[i]=dp[i−1]+dp[i−2]
初始化:
- dp[0]=1
- dp[1]=1
迭代计算:
- 从 i=2 开始,依次计算 dp[i] 直到 dp[n]。
结果:
- 返回 dp[n] 作为斐波那契数列的第 n 项。
2. 算法步骤
初始化:
- 定义一个数组
dp[n+1]
用于存储斐波那契数列的每个值。 - 初始化
dp[0] = 1
和dp[1] = 1
。
迭代计算:
- 从
i = 2
开始,依次计算dp[i] = dp[i-1] + dp[i-2]
,直到i = n
。
返回结果:
- 返回
dp[n]
作为斐波那契数列的第 nn 项。
3. 图示法表示步骤
假设我们要计算斐波那契数列的第 5 项 F(5)。
步骤 1:初始化
dp[0] = 1
dp[1] = 1
步骤 2:迭代计算
i = 2:
dp[2] = dp[1] + dp[0] = 1 + 1 = 2
i = 3:
dp[3] = dp[2] + dp[1] = 2 + 1 = 3
i = 4:
dp[4] = dp[3] + dp[2] = 3 + 2 = 5
i = 5:
dp[5] = dp[4] + dp[3] = 5 + 3 = 8
最终结果
- F(5)=8
4. 代码关键行注释
#include <iostream>
#include <vector>
using namespace std;
// 斐波那契数列(动态规划)
int fib(int n) {
if (n == 0) return 1; // 递归终止条件,n=0时返回1
if (n == 1) return 1; // 递归终止条件,n=1时返回1
vector<int> dp(n + 1); // 定义dp数组
dp[0] = 1; // 初始化dp[0]
dp[1] = 1; // 初始化dp[1]
for (int i = 2; i <= n; i++) { // 迭代计算dp[i]
dp[i] = dp[i - 1] + dp[i - 2]; // 递推公式
}
return dp[n]; // 返回结果
}
int main() {
int n = 5; // 定义n的值
cout << "The " << n << "th Fibonacci number is " << fib(n) << endl; // 输出结果
return 0; // 程序结束
}
5. 时间复杂度
- 时间复杂度:
- 动态规划的时间复杂度为 O(n),因为需要计算每个 dp[i] 从 2 到 n。
6. 总结
动态规划是一种高效的算法,用于解决斐波那契数列问题。通过存储子问题的结果,可以避免重复计算,从而提高效率。该算法的时间复杂度为线性级别,适用于各种大小的 n。