动态规划与贪婪-剪绳子

题目描述

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],...,k[m]。请问k[0]xk[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

如  输入 8 ,   输出 18

解题思路

  • 递归

设f(n)为长度为n的绳子剑成若干段后的最大乘积。如果我们在第 i 处只剪一刀,那么绳子会分成两个部分,那么

f(n) = max ( f(i) * f(n-i) )     0<i<n

核心代码为,求解过程是自上而下

# -*- coding:utf-8 -*-
class Solution:
    def cutRope(self, number):
        # write code here
        if number == 1:
            return 0
        if number == 2:
            return 1
        if number == 3:
            return 2
        return self.iterate(number)
    def iterate(self, number):
        if number <= 4:
            return number
        ans = 0
        for i in range(1, number):
            ans = max(ans, self.iterate(i) * self.iterate(number-i))
        return ans
  • 动态规划

使用动态规划,自下而上进行求解

# -*- coding:utf-8 -*-
class Solution:
    def cutRope(self, number):
        # write code here
        if number == 1:
            return 0
        if number == 2:
            return 1
        if number == 3:
            return 2
        ans = [0]*(number+1)
        ans[1] = 1
        ans[2] = 2
        ans[3] = 3
        for i in range(4, number+1):
            temp_max = 0
            for j in range(1, int(i)/2+1):
                temp_max = max(ans[j]*ans[i-j], temp_max)
            ans[i] = temp_max
        return ans[number]
  • 贪心算法

该方法需要一定的数学功底,可以参考

https://blog.nowcoder.net/n/915eab44a70b49ef92abdc93f8993432?f=comment

 

 

 

 

 

### 截绳子算法题的动态规划最优解 #### 动态规划的核心思想 动态规划是一种通过将复杂问题分解为更简单的子问题来解决问题的技术。对于“截绳子”这个问题,可以通过动态规划找到最优解。如果要求一个问题的最优解,并且该问题能够被划分为多个相互独立的子问题,那么可以利用动态规划的思想解决[^2]。 #### 解题思路分析 在“截绳子”的问题中,目标是将一根长度为 `n` 的绳子切成多(至少切一刀),使这些的乘积最大化。为了达到这个目的,我们可以定义状态转移方程: 设 `dp[i]` 表示长度为 `i` 的绳子所能获得的最大乘积,则有如下关系: \[ dp[i] = \max(j \times (i-j), j \times dp[i-j]) \quad \text{for} \quad 1 \leq j < i \] 其中,\(j\) 是切割的第一绳子的长度,而 \(i-j\) 则表示剩余部分的长度。这里有两种情况需要比较:一是直接将绳子切成两并取其乘积;二是先切下一后再对剩下部分应用动态规划的结果。 时间复杂度方面,由于我们需要遍历所有的可能分割位置 \(j\) 并更新每一个 \(dp[i]\),因此总的时间复杂度为 \(O(n^2)\)[^1]。 以下是基于上述逻辑编写的 Python 实现代码: ```python def cuttingRope(n): if n <= 3: return n - 1 dp = [0] * (n + 1) dp[2], dp[3] = 1, 2 # 初始化基础条件 for length in range(4, n + 1): max_product = 0 for cut_position in range(1, length // 2 + 1): product = dp[cut_position] * dp[length - cut_position] if product > max_product: max_product = product dp[length] = max(max_product, (length//2)*(length-length//2)) return dp[n] ``` 此函数首先处理了一些边界情况 (\(n\leq3\)) ,然后初始化数组 `dp[]` 来存储中间结果。接着迭代填充整个表格直到最终答案存入 `dp[n]` 中。 另外还存在一种贪婪算法的方式可以直接得出近似最佳解答,即尽可能多地掉长度为3的部分除非最后只剩余4单位则拆分两个2单位片[^5]。 #### 结论 综上所述,“截绳子”问题是典型的动态规划案例之一,它展示了如何通过构建合适的递推关系式逐步逼近全局最优化方案的过程。尽管也有其他更快捷但未必完全精确的方法比如贪婪策略可用,但对于追求绝对精度的应用场景来说,采用动态规划仍是首选途径[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值