当前位置: 首页 > news >正文

算法-动态规划-钢条切割问题

钢条切割问题是一个经典的动态规划问题,旨在通过切割钢条获得最大收益。以下是详细解释和解决方案:

问题描述

  • 给定长度为 n 的钢条和价格表 p,其中 p[i] 表示长度为 i 的钢条的价格(i = 1, 2, ..., n)。
  • 目标:找到切割方案,使销售收益最大化。

动态规划解法

核心思想
  • 最优子结构:长度为 n 的钢条的最优解包含子问题的最优解(例如,切割成两段后,每段的最优解)。
  • 递归关系
    • r[i] 为长度为 i 的钢条的最大收益。

    • 初始值:r[0] = 0(长度为 0 的钢条收益为 0)。

    • 递推公式:

      r[i] = max_{1≤j≤min(i, m)} { p[j] + r[i - j] }

      其中 m 是价格表的最大长度(即 m = len(p)),j 是第一段切割的长度。

算法步骤
  1. 初始化

    • 创建数组 r[0..n] 存储最大收益,r[0] = 0
    • 创建数组 s[0..n] 存储切割方案,s[i] 记录长度为 i 时第一段切割的长度。
  2. 自底向上计算

    • 遍历长度 i 从 1 到 n
      • 初始化 q = -∞(临时变量,存储当前最大收益)。
      • 遍历切割长度 j 从 1 到 i
        • j 超出价格表范围(j > m),跳过。
        • 否则,计算收益 temp = p[j] + r[i - j]
        • temp > q,更新 q = temp 并记录 s[i] = j
      • 设置 r[i] = q
  3. 回溯切割方案

    • i = n 开始:
      • 输出 s[i](第一段切割长度)。
      • 更新 i = i - s[i],重复直到 i = 0

时间复杂度和空间复杂度

  • 时间复杂度O(n^2)(双重循环)。
  • 空间复杂度O(n)(存储 rs 数组)。

示例演示

假设 n = 4,价格表 p = [0, 1, 5, 8, 9](索引从 1 开始):

  • 计算过程
    • i=1j=1r[1] = p[1] + r[0] = 1s[1]=1
    • i=2j=11 + r[1]=2j=25 + r[0]=5r[2]=5, s[2]=2
    • i=3j=38 + r[0]=8r[3]=8, s[3]=3
    • i=4j=25 + r[2]=10r[4]=10, s[4]=2
  • 切割方案4 → 2 + 2(收益 5 + 5 = 10)。

**代码实现(Python)

def rod_cutting(n, p):m = len(p) - 1  # 价格表最大长度(索引从1开始)r = [-10**18] * (n + 1)  # 最大收益数组s = [0] * (n + 1)         # 切割方案数组r[0] = 0     # 初始化# 动态规划填表for i in range(1, n + 1):q = -10**18for j in range(1, i + 1):if j > m:  # j超出价格表范围continuetemp = p[j] + r[i - j]if temp > q:q = temps[i] = jr[i] = q# 回溯切割方案solution = []i = nwhile i > 0:solution.append(s[i])i -= s[i]return r[n], solution

示例

n = 4
p = [0, 1, 5, 8, 9] # p[0]无效,p[1]=1, p[2]=5, …
max_profit, cuts = rod_cutting(n, p)
print(“最大收益:”, max_profit) # 输出: 10
print(“切割方案:”, cuts) # 输出: [2, 2]

关键点

  • 价格表处理:索引从 1 开始,p[j] 直接对应长度 j 的价格。
  • 边界处理:当 j > m 时跳过(长度超出价格表范围)。
  • 方案回溯:利用 s 数组逐步还原切割段。

此方法高效地解决了钢条切割问题,适用于任意长度的钢条和价格表。

http://www.lryc.cn/news/573840.html

相关文章:

  • 简单工厂模式,工厂模式和注册工厂模式
  • Go 循环依赖的依赖注入解决方案详解
  • Cache Travel-09-从零开始手写redis(17)v1.0.0 全新版本架构优化+拓展性增强
  • AI三步诊断心理:比ChatGPT更懂人心
  • C#Halcon从零开发_Day14_AOI缺陷检测策略1_Bolb分析+特征分析_饼干破损检测
  • JavaScript性能优化实战
  • MySQL索引分类有哪些?
  • RA4M2开发IOT(9)----动态显示MEMS数据
  • 基于python代码的通过爬虫方式实现TK下载视频(2025年6月)
  • 支付宝携手HarmonyOS SDK实况窗,开启便捷停车生活
  • 湖北理元理律师事务所:构建可持续债务优化的双轨解法
  • all()函数和any()函数
  • Linux->进程概念(精讲)
  • JavaEE-Mybatis进阶
  • 图灵完备之路(数电学习三分钟)----门的多路化
  • 创客匠人行业洞察:创始人 IP 的核心能力构建与长期主义实践
  • YSYX学习记录(十一)
  • Python中使用RK45方法求解微分方程的详细指南
  • mysql 加锁算法 详解
  • OC—多界面传值
  • JAVA集合篇--深入理解ConcurrentHashMap图解版
  • Java面试复习指南:Java基础、面向对象编程与并发编程
  • 【论文阅读】 智能用户界面的用户接受度研究——以旋翼机飞行员辅助系统为例( Miller, C.A. Hannen, M.D. in 1999)
  • uni-app项目实战笔记21--uniapp缓存的写入和读取
  • 【代码解析】opencv 安卓 SDK sample - 1 - HDR image
  • Spring JDBC配置与讲解
  • Python 使用Gitlab Api
  • Kafka与Zookeeper在linux上的下载记录
  • LLMs之Embedding:Qwen3 Embedding的简介、安装和使用方法、案例应用之详细攻略
  • ms-swift 部分命令行参数说明