本文实现一个动态规划(Dynamic Programming)的算法案例,解决经典的斐波那契数列问题。
问题描述
斐波那契数列的定义如下:
F(0) = 0
F(1) = 1
F(n) = F(n-1) + F(n-2)
(当n >= 2
时)
给定一个整数 n
,计算斐波那契数列的第 n
项。
C++代码实现
#include <iostream>
#include <vector>
using namespace std;
// 动态规划实现斐波那契数列
int fibonacci(int n) {
if (n <= 1) return n; // 边界条件
vector<int> dp(n + 1); // 动态规划表
dp[0] = 0; // 初始化
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2]; // 状态转移方程
}
return dp[n]; // 返回结果
}
int main() {
int n = 10; // 计算第10项
cout << "斐波那契数列的第 " << n << " 项是: " << fibonacci(n) << endl;
return 0;
}
关键解析
- 动态规划思想:
- 将问题分解为子问题,通过存储子问题的解避免重复计算。
- 状态转移方程:
dp[i] = dp[i-1] + dp[i-2]
- 时间复杂度:
O(n)
,只需遍历一次。 - 空间复杂度:
O(n)
,使用了一个数组存储中间结果。 - 优化空间复杂度:
- 如果只关心最终结果,可以用两个变量代替数组,将空间复杂度优化为
O(1)
。
- 如果只关心最终结果,可以用两个变量代替数组,将空间复杂度优化为
优化版本(空间复杂度 O(1)
)
int fibonacciOptimized(int n) {
if (n <= 1) return n;
int prev1 = 0, prev2 = 1;
for (int i = 2; i <= n; i++) {
int current = prev1 + prev2;
prev1 = prev2;
prev2 = current;
}
return prev2;
}
输出示例
斐波那契数列的第 10 项是: 55
应用场景
- 计算斐波那契数列
- 解决其他具有重叠子问题的动态规划问题(如背包问题、最长公共子序列等)