动态规划实战:从斐波那契数列到解码方法的优雅跨越

1. 动态规划入门:从斐波那契数列说起

第一次接触动态规划时,很多人都会被这个高大上的名字吓到。其实它的核心思想非常简单——把大问题拆解成小问题,并且记住已经解决过的小问题答案。就像我们小时候背乘法口诀表一样,记住"三七二十一"之后,下次就不用再重新计算了。

斐波那契数列是最经典的动态规划案例。这个数列的特点是:每个数字都是前两个数字之和。用代码表示就是:

def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

这个递归解法虽然直观,但效率极低。比如计算fib(5)时,会重复计算fib(3)两次、fib(2)三次。当n变大时,这种重复计算会呈指数级增长。

动态规划的精妙之处就在于它解决了这个问题。我们可以用一个数组来存储已经计算过的结果:

def fib(n):
    dp = [0] * (n + 1)
    dp[1] = 1
    for i in range(2, n + 1):
        dp[i] = dp[i-1] + dp[i-2]
    return dp[n]

这样就把时间复杂度从O(2^n)降到了O(n)。我第一次用这个方法时,感觉就像发现了新大陆——原来算法优化可以这么简单直接!

2. 爬楼梯问题:斐波那契的变种

LeetCode第70题"爬楼梯"是斐波那契数列的完美变种。题目说:假设你正在爬楼梯,每次可以爬1或2个台阶,问有多少种不同的方法可以爬到第n阶。

我第一次做这题时,尝试用枚举法列出了前几项:

  • 1阶:1种(1)
  • 2阶:2种(1+1,2)
  • 3阶:3种(1+1+1,1+2,2+1)
  • 4阶:5种...

突然发现这不就是斐波那契数列吗?因为要到达第n阶,要么从n-1阶跨1步上来,要么从n-2阶跨2步上来。所以状态转移方程就是:

dp[n] = dp[n-1] + dp[n-2]

这个发现让我兴奋不已。原来很多看似不同的问题,背后可能是同一个数学模型。代码实现几乎和斐波那契数列一样:

def climbStairs(n):
    if n <= 2:
        return n
    a, b = 1, 2
    for _ in range(3, n+1):
        a, b = b, a + b
    return b

这里我用了空间优化的写法,只保留前两

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值