区间动态规划例题:切棍子的最小成本问题(进阶版)
字数 1999 2025-11-08 10:02:38
区间动态规划例题:切棍子的最小成本问题(进阶版)
题目描述
你有一根长度为 n 的木棍,它由 0 到 n 的整数位置标记。现给定一个整数数组 cuts,其中 cuts[i] 表示需要在木棍的该位置进行切割。每次切割的成本等于当前木棍的长度。要求确定切割顺序,使得所有切割完成后的总成本最小,并返回最小总成本。
例如,木棍长度 n = 7,切割位置 cuts = [1, 3, 4, 5]。若按顺序在位置 4、3、1、5 切割,总成本计算如下:
- 第一次切割长度为 7 的木棍在位置 4,成本为 7,得到两段长度分别为 4 和 3 的木棍。
- 第二次切割长度为 4 的木棍在位置 3(相对位置需换算),成本为 4,得到两段长度分别为 3 和 1 的木棍。
- 第三次切割长度为 3 的木棍在位置 1,成本为 3,得到两段长度分别为 1 和 2 的木棍。
- 第四次切割长度为 3 的木棍在位置 5(相对位置需换算),成本为 3。
总成本为 7 + 4 + 3 + 3 = 17。但存在更优顺序使总成本更低。
解题过程
步骤 1:问题分析与状态定义
- 关键点:每次切割的成本取决于当前木棍的长度,而切割顺序影响后续木棍的长度。
- 区间动态规划适用性:将木棍视为区间
[left, right],其中left和right是木棍的端点(包括切割点)。定义dp[i][j]表示在区间[cuts[i], cuts[j]]内(即端点cuts[i]和cuts[j]之间的木棍段)进行所有必要切割的最小总成本。 - 预处理:将切割点数组
cuts排序,并加入边界点 0 和n,形成扩展切割点数组c。例如,n = 7,cuts = [1, 3, 4, 5]扩展为c = [0, 1, 3, 4, 5, 7]。 - 状态定义:设
dp[i][j]表示在区间[c[i], c[j]]内(即从第i个切割点到第j个切割点之间的木棍段)进行所有内部切割(不包括端点i和j)的最小成本。区间长度j - i ≥ 2时才有切割意义。
步骤 2:状态转移方程
- 基础情况:若区间内无切割点(即
j - i == 1),则dp[i][j] = 0(无需切割)。 - 一般情况:对于区间
[i, j],枚举第一个切割点k(i < k < j),将区间分为[i, k]和[k, j]。切割成本为当前木棍长度c[j] - c[i],加上左右子区间的最小成本:
dp[i][j] = min(dp[i][k] + dp[k][j]) + (c[j] - c[i]),其中k遍历i+1到j-1。 - 解释:选择切割点
k后,木棍被分为两段,成本为当前段长度;左右子区间独立切割,其最小成本已通过子问题计算。
步骤 3:计算顺序与初始化
- 初始化:所有
dp[i][j]初始化为 0(当j - i == 1)或一个大数(如INT_MAX)。 - 计算顺序:按区间长度从小到大计算。外层循环为区间长度
len从 2 到m-1(m为扩展切割点数组长度),内层循环为起点i从 0 到m - len,终点j = i + len。 - 示例:扩展切割点
c = [0, 1, 3, 4, 5, 7],m = 6。计算顺序:len = 2:区间如[0,1],[1,3]...(无内部切割点,成本为 0)。len = 3:区间如[0,3](内部切割点k=1),dp[0][3] = min(dp[0][1] + dp[1][3]) + (3-0) = 0 + 0 + 3 = 3。- 逐步计算至
len = 5(区间[0,7])。
步骤 4:结果提取与复杂度
- 结果:最终答案为
dp[0][m-1],即整个木棍[0, n]的最小切割成本。 - 时间复杂度:O(m³),其中
m为扩展切割点数量(通常m = |cuts| + 2)。空间复杂度:O(m²)。
示例验证
对 n = 7, cuts = [1, 3, 4, 5],扩展 c = [0, 1, 3, 4, 5, 7]。
- 计算
dp[0][5]:枚举k = 1,2,3,4,取最小值:k=1:dp[0][1] + dp[1][5] + 7→ 需先计算子区间。- 最终得最小成本为 16(如顺序 1,3,4,5 或 3,1,4,5)。
对比暴力顺序(成本 17),动态规划找到更优解。
通过以上步骤,可系统解决该问题,确保切割顺序最优且成本最小。