从递归到DP(动态规划)

本文通过斐波那契数列的例子,详细解释了动态规划(DP)的概念,从朴素的递归算法出发,过渡到记忆化搜索,再到DP的自底向上解法。介绍了DP的最优子结构、状态转移方程、边界和重叠子问题,并讨论了DP与记忆化搜索在时间复杂度和空间复杂度上的区别,以及在解题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从递归到DP

那么,首先让我们看一看什么是DP(动态规划)

百度百科曰:

动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。20世纪50年代初,美国数学家贝尔曼1(R.Bellman)等人在研究多阶段决策过程的优化问题时,提出了著名的最优化原理,从而创立了动态规划。动态规划的应用极其广泛,包括工程技术、经济、工业生产、军事以及自动化控制等领域,并在背包问题、生产经营问题、资金管理问题、资源分配问题、最短路径问题和复杂系统可靠性问题等中取得了显著的效果

你看懂了么?

实话告诉你,我也没看懂。

那那那那那那么,就让我们从斐波那契数列一步一步到DP吧

朴素的递归算法

某年某月某日,在朔月的带领下,我学会了递归。于是,我就用递归写了一个斐波那切数列:

int f(n){
   
   
    if (n == 0){
   
   
        return 0;
    }
    if (n == 1){
   
   
        return 1;
    }
    return f(n-1) + f(n-2);
}

于是,让我们计算一下本代码的时间复杂度:

……

……

最终,我们得到,递归的时间复杂度是:
O ( 2 n ) O(2^n) O(2n)
啊啊(脑补)

从递归到记忆化搜索

又是在某年某月某日,在 Thijs_Bitkid的带领下,我又学会了记忆化搜索。于是就有:

int memory[10005] = {
   
   0};
int f(n){
   
   
    if (memory[n]){
   
   
        return memory[n];
    }
    if (n == 0){
   
   
        memory[n] = 0;
        return 0;
    }
    if (n == 1){
   
   
        memory[n] = 1;
        return 1;
    }
    memory[n] = f(n-1) + f(n-2);
    return memory[n];
}

好的,我们看一看它的时间复杂度:

计算中……

输出中……
O ( n ) O(n) O(n)
nice(脑补)

从记忆化搜索到DP

我们看到,在记忆化搜索中,函数从 f ( n ) f(n) f(n)开始执行,直到 f ( 1 ) f(1) f(1),因此,我们称之

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值