动态规划的两种方式

本文介绍了动态规划中自底向上和自上向下的两种处理方式,并通过钢铁切割问题的实例来展示这两种方法的具体实现。提供了详细的算法代码示例。

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

动态规划问题的两种处理方式:自底向上和自上向下。

各自有各自的优势,以算法导论上的钢铁切割为例,贴出代码缓存一下。

int maxvalue(int cur_length, int left)
{
    int value1 = 0;
    if (a[left] || left == 0)
    {
        value1 = a[left];
    }
    else
    {
        value1 = maxvalue(1, left - 1);
        a[left] = value1;
    }
    int temp = value[cur_length] + value1;
    if (left == 0)
    {
        return temp;
    }
    else
    {
        int cur_temp = maxvalue(cur_length + 1, left - 1);
        if (temp > cur_temp)
        {
            return temp;
        }
        else
        {
            return cur_temp;
        }
    }
}

int maxvalue(int length)
{
    for (int i = 1; i < length; i++)
    {
        int p = 0, temp = 0;
        for (int j = 1; j <= i; j++)
        {
            temp = value[j] + a[i];
            if (p < temp)
            {
                p = temp;
                root[i] = j;//每次记忆当前取的长度
            }
        }
        a[i] = p;
    }
}
### 动态规划两种方法及其应用 动态规划是一种通过将复杂问题分解为更小的子问题来解决优化问题的方法。根据解决问题的方式动态规划可以分为两种主要方法:**自顶向下(递归加记忆化搜索)**和**自底向上(迭代)**。 #### 自顶向下(递归加记忆化搜索) 自顶向下的动态规划方法基于递归的思想,并通过记忆化技术避免重复计算子问题。这种方法从问题的最终状态开始,逐步递归地求解子问题,同时将每个子问题的结果存储在表中,以便后续使用时直接查表[^1]。 ##### 应用场景 自顶向下的方法适用于那些可以通过递归定义状态转移方程的问题。例如,在斐波那契数列的计算中,可以通过递归调用并结合记忆化技术来避免重复计算相同的子问题。 ```python # 使用记忆化的递归实现斐波那契数列 def fibonacci(n, memo={}): if n in memo: return memo[n] if n <= 1: return n memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo) return memo[n] ``` #### 自底向上(迭代) 自底向上的动态规划方法采用迭代的方式,从最简单的子问题开始逐步构建到最终问题的解。这种方法通常需要定义一个数组或表格来存储中间结果,从而确保每个子问题只被计算一次[^1]。 ##### 应用场景 自底向上的方法适用于那些可以通过迭代方式构建状态转移方程的问题。例如,在背包问题中,可以通过迭代更新二维数组中的值来记录不同容量下能够获得的最大价值。 ```python # 使用自底向上的方法解决0-1背包问题 def knapsack(weights, values, capacity): n = len(weights) dp = [[0] * (capacity + 1) for _ in range(n + 1)] for i in range(1, n + 1): for w in range(capacity + 1): if weights[i - 1] <= w: dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - weights[i - 1]] + values[i - 1]) else: dp[i][w] = dp[i - 1][w] return dp[n][capacity] ``` #### 区别 两种方法的主要区别在于解决问题的方向和实现方式。自顶向下的方法从问题的最终状态出发,通过递归逐步求解子问题,并利用记忆化技术避免重复计算;而自底向上的方法则从最简单的子问题开始,通过迭代逐步构建到最终问题的解。自顶向下的方法更接近于自然的递归思维方式,但可能由于递归调用栈的限制而导致性能问题。相比之下,自底向上的方法虽然需要手动构建状态转移过程,但在大多数情况下具有更高的效率和更低的空间开销[^3]。 ### 总结 无论是自顶向下还是自底向上的动态规划方法,其核心思想都是通过保存已解决的子问题的结果来避免重复计算,从而提高算法效率。选择哪种方法取决于具体问题的特点和个人偏好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值