递推算法
登录以参加训练计划
好的!递推算法是通过已知条件逐步推导出结果的算法,非常适合解决有明确递推公式的问题。下面用超详细图解+生活化例子帮你掌握这个重要算法!🚀
🌟 递推算法核心思想
- 已知起点:明确初始条件(比如第1项的值)
- 递推公式:找到第n项与前面若干项的关系
- 顺序计算:像多米诺骨牌一样,逐个推导后续结果
🆚 递推 vs 递归
递推 | 递归 | |
---|---|---|
实现 | 循环迭代 | 函数调用自身 |
效率 | 高(无重复计算) | 低(可能有重复计算) |
方向 | 自底向上(从已知推未知) | 自顶向下(分解问题) |
📚 经典递推问题
1. 斐波那契数列
问题:已知F(0)=0, F(1)=1,求F(n)=F(n-1)+F(n-2)
递推解法:
int fib(int n) {
if(n == 0) return 0;
int a = 0, b = 1;
for(int i=2; i<=n; i++){
int c = a + b;
a = b;
b = c;
}
return b;
}
优化:空间复杂度从O(n)降到O(1)
2. 数塔问题(动态规划基础)
问题:从塔顶到底层路径的最大和
输入示例:
5
3 8
8 1 0
2 7 4 4
递推公式:dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + a[i][j]
// 从底向上递推
for(int i = n-2; i >=0; i--) {
for(int j=0; j<=i; j++) {
dp[i][j] = max(dp[i+1][j], dp[i+1][j+1]) + a[i][j];
}
}
cout << dp[0][0]; // 输出最大值
3. 组合数计算(杨辉三角)
递推公式:C(n,k) = C(n-1,k-1) + C(n-1,k)
代码实现:
int C[100][100];
void init() {
for(int i=0; i<=n; i++){
C[i][0] = 1;
for(int j=1; j<=i; j++){
C[i][j] = C[i-1][j-1] + C[i-1][j];
}
}
}
💡 递推算法应用场景
- 数列问题:斐波那契、卡特兰数等
- 动态规划基础:背包问题、最短路径
- 组合数学:排列组合计算
- 图形问题:数塔、矩阵路径
✅ 递推解题步骤
- 确定状态:定义dp[i]的含义
- 找到递推式:分析状态转移关系
- 初始化:设置起始条件
- 计算顺序:确保计算时所需的前驱状态已计算
- 边界处理:处理n=0等特殊情况
🌰 实战案例:爬楼梯问题
问题:每次爬1或2阶,n阶楼梯有多少种走法?
递推分析:
- dp[1] = 1(只走1步)
- dp[2] = 2(1+1或2)
- dp[i] = dp[i-1] + dp[i-2] (i≥3)
int climbStairs(int n) {
if(n <= 2) return n;
int a=1, b=2, c;
for(int i=3; i<=n; i++){
c = a + b;
a = b;
b = c;
}
return b;
}
🚀 性能优化技巧
- 滚动数组:将二维dp压缩为一维(如斐波那契中的a,b,c)
- 状态压缩:只保留必要的前驱状态
- 预处理:提前计算常用结果(如组合数表)
❗ 注意事项
- 初始条件正确性:比如dp[0]是否需要特殊处理
- 递推顺序:确保计算当前状态时所需状态已计算
- 数据范围:防止整数溢出(使用long long)
📝 练习题
- 蜜蜂路线:蜜蜂从蜂房A到B只能向右走,求路径数(类似斐波那契)
- 过河卒:棋盘上卒子从A到B,避开马的控制点,求路径数
- 数的划分:将整数n分成k份的不同方法数(递推式思考)
需要哪道题的详细递推分析?😊
- 参加人数
- 0
- 创建人