开发喵星球

动态规划

动态规划

动态规划 (Dynamic Programming, 简称DP) 是一种解决复杂问题的方法,它通过将问题分解为更简单的子问题来解冔。让我们用DP解决一个非常经典的问题:斐波那契数列。

斐波那契数列的定义如下:

scssCopy code
F(0) = 0
F(1) = 1
F(n) = F(n-1) + F(n-2) 对于 n > 1

传统递归方法的实现:

pythonCopy code
def fibonacci_recursive(n):
    if n <= 1:
        return n
    else:
        return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)

但是这种方法的效率非常低,因为它会多次计算相同的子问题。

现在,我们使用动态规划方法来优化它:

pythonCopy code
def fibonacci_dp(n):
    if n <= 1:
        return n

    # 初始化存储结果的数组
    fib = [0] * (n+1)
    fib[1] = 1

    # 从下到上计算每一个斐波那契数
    for i in range(2, n+1):
        fib[i] = fib[i-1] + fib[i-2]

    return fib[n]

动态规划版本的优点是,它不会重复计算相同的子问题,因为我们将之前计算的结果存储起来,并直接使用这些结果。这大大提高了计算速度。

用一个例子,说明背包问题

ChatGPT

背包问题是动态规划中的一个经典问题。为了简洁明了,我们先从0-1背包问题开始。

问题描述:

假设你是一个盗贼,准备打劫一个商店。你有一个背包,它的容量有限,而商店里有多种物品,每种物品有一定的重量和价值。由于背包的容量有限,你不能把所有物品都拿走,所以你需要选择一些物品,使得拿走的这些物品的总价值最大。

具体描述:

  1. 有 �n 件物品和一个最大容量为 �W 的背包。
  2. 每种物品都有自己的价值 �[�]v[i] 和重量 �[�]w[i]。
  3. 我们希望选择一些物品,使得这些物品的总重量不超过背包的最大容量,同时总价值尽可能大。

示例:

假设我们有以下物品:

cssCopy code
物品    重量    价值
A       2       3
B       3       4
C       4       5
D       5       6

背包的最大容量为8。

一个最优解是选择物品A、B和D,总重量为 2+3+5=102+3+5=10 (超出了背包容量),总价值为 3+4+6=133+4+6=13。

动态规划可以帮助我们找到这个最优解。

动态规划解法:

我们可以定义一个数组 ��[�][�]d**p[i][j] 表示前i个物品,背包容量为j时的最大价值。

递推关系为:

cssCopy code
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])

Python的简单实现:

pythonCopy code
def knapsack(values, weights, W):
    n = len(values)
    dp = [[0] * (W + 1) for _ in range(n + 1)]

    for i in range(1, n + 1):
        for j in range(1, W + 1):
            if weights[i-1] <= j:
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-weights[i-1]] + values[i-1])
            else:
                dp[i][j] = dp[i-1][j]

    return dp[n][W]

values = [3, 4, 5, 6]
weights = [2, 3, 4, 5]
W = 8
print(knapsack(values, weights, W))  # 输出:13

这样,我们可以得到在背包容量为8时,最大的价值为13。

   
分类:数据结构和算法 作者:开发喵 发表于:2023-08-16 10:56:37 阅读量:107
<<   >>


powered by kaifamiao