动态规划在算法设计中的应用

动态规划是一种常见的算法设计思想,通过拆解问题,利用子问题的解来求解原问题。以下是一些使用动态规划的经典问题及其相应的解决方案。

1. 斐波那契数列

首先,我们介绍了计算斐波那契数列的两种方式:递归和非递归。递归实现简洁但效率较低,而非递归方式采用动态规划,通过递推式和重复子问题的思想,避免了重复计算,提高了效率。

# 斐波那契数列
def fibonacci(n):
    if n == 1 or n == 2:
        return 1
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)

# 斐波那契数列 非递归
def fibonacci_no_rec(n):
    f = [0, 1, 1]
    if n > 2:
        for i in range(n - 2):
            num = f[-1] + f[-2]
            f.append(num)
    return f[n]

2. 钢条切割问题

接着,我们解决了钢条切割问题,其中包括自顶向下和自底向上两种实现方式。这个问题通过动态规划的方式,通过构建递推关系,避免了重复计算,提高了求解效率。

# 钢条切割问题
# 自顶向下实现
p = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30]

def cut_rod_rec_1(p, n):
    if n == 0:
        return 0
    else:
        res = p[n]
        for i in range(1, n):
            res = max(res, cut_rod_rec_1(p, i) + cut_rod_rec_1(p, n - i))
        return res

print(cut_rod_rec_1(p, 9))

# 自底向上
def cut_rod_dp(p, n):
    r = [0]
    for i in range(1, n + 1):
        res = 0
        for j in range(1, i + 1):
            res = max(res, p[j] + r[i - j])
        r.append(res)
    return r[n]

print(cut_rod_dp(p, 9))

3. 最长公共子序列

最后,我们介绍了最长公共子序列问题,通过构建二维表格来记录子问题的解,进而求解整个问题。该问题展示了动态规划在字符串匹配等领域的广泛应用。

# 最长公共子序列
def lcs_length(x, y):
    m = len(x)
    n = len(y)
    c = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if x[i - 1] == y[j - 1]:
                c[i][j] = c[i - 1][j - 1] + 1
            else:
                c[i][j] = max(c[i - 1][j], c[i][j - 1])
    for _ in c:
        print(_)
    return c[m][n]

print(lcs_length("ABCBDAB", "BDCABA"))

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值