石子合并问题(环形版本)
字数 1115 2025-11-14 05:45:48

石子合并问题(环形版本)

题目描述:
假设有n堆石子排成一个环形,每堆石子有一定的数量。现在要将这些石子合并成一堆,合并规则是每次只能合并相邻的两堆石子,合并的代价是这两堆石子的数量之和。目标是找到一种合并顺序,使得总合并代价最小。

解题过程:

  1. 问题分析:
  • 环形排列意味着第一堆和最后一堆石子也是相邻的
  • 我们需要找到合并顺序,使得总代价最小
  • 这是一个经典的区间动态规划问题
  1. 关键思路:
  • 将环形问题转化为线性问题:将原数组复制一份接在后面,这样环形问题就变成了长度为2n的线性问题
  • 对于每个可能的起点,计算长度为n的线性石子合并问题
  1. 状态定义:
    定义dp[i][j]表示合并从第i堆到第j堆石子的最小代价(i ≤ j)

  2. 状态转移方程:
    对于区间[i, j],我们枚举最后一次合并的位置k(i ≤ k < j):
    dp[i][j] = min(dp[i][k] + dp[k+1][j] + sum[i][j])
    其中sum[i][j]表示从第i堆到第j堆石子的总数

  3. 具体步骤:

步骤1:预处理前缀和数组

  • 创建前缀和数组prefix,其中prefix[i]表示前i堆石子的总和
  • 这样sum[i][j] = prefix[j] - prefix[i-1]

步骤2:环形转线性

  • 将原石子数组arr复制一份,得到新数组newArr,长度为2n
  • 例如:原数组[1,2,3] → 新数组[1,2,3,1,2,3]

步骤3:动态规划求解

  • 初始化dp表,dp[i][i] = 0(单堆石子不需要合并)
  • 按区间长度从小到大计算:
    • 先计算长度为2的区间
    • 然后计算长度为3的区间
    • 依此类推,直到长度为n

步骤4:寻找最优解

  • 在所有的长度为n的区间[i, i+n-1](0 ≤ i < n)中,找到dp[i][i+n-1]的最小值
  1. 示例演示:
    假设石子堆为[3,4,5,2](环形)

步骤1:扩展数组为[3,4,5,2,3,4,5,2]

步骤2:计算各个区间的最小代价:

  • 区间[0,3]:合并顺序3,4,5,2
  • 区间[1,4]:合并顺序4,5,2,3
  • 区间[2,5]:合并顺序5,2,3,4
  • 区间[3,6]:合并顺序2,3,4,5

步骤3:比较所有可能起点的最小代价,取最小值

  1. 时间复杂度:O(n³)
  • 需要枚举区间起点、终点和分割点
  • 对于环形版本,需要计算2n长度的数组,但实际有效计算仍然是O(n³)
  1. 空间复杂度:O(n²)
  • 需要维护n×n的dp表

这种方法通过环形转线性的技巧,将复杂的环形问题转化为熟悉的线性石子合并问题,是解决环形区间动态规划的经典方法。

石子合并问题(环形版本) 题目描述: 假设有n堆石子排成一个环形,每堆石子有一定的数量。现在要将这些石子合并成一堆,合并规则是每次只能合并相邻的两堆石子,合并的代价是这两堆石子的数量之和。目标是找到一种合并顺序,使得总合并代价最小。 解题过程: 问题分析: 环形排列意味着第一堆和最后一堆石子也是相邻的 我们需要找到合并顺序,使得总代价最小 这是一个经典的区间动态规划问题 关键思路: 将环形问题转化为线性问题:将原数组复制一份接在后面,这样环形问题就变成了长度为2n的线性问题 对于每个可能的起点,计算长度为n的线性石子合并问题 状态定义: 定义dp[ i][ j ]表示合并从第i堆到第j堆石子的最小代价(i ≤ j) 状态转移方程: 对于区间[ i, j],我们枚举最后一次合并的位置k(i ≤ k < j): dp[ i][ j] = min(dp[ i][ k] + dp[ k+1][ j] + sum[ i][ j ]) 其中sum[ i][ j ]表示从第i堆到第j堆石子的总数 具体步骤: 步骤1:预处理前缀和数组 创建前缀和数组prefix,其中prefix[ i ]表示前i堆石子的总和 这样sum[ i][ j] = prefix[ j] - prefix[ i-1 ] 步骤2:环形转线性 将原石子数组arr复制一份,得到新数组newArr,长度为2n 例如:原数组[ 1,2,3] → 新数组[ 1,2,3,1,2,3 ] 步骤3:动态规划求解 初始化dp表,dp[ i][ i ] = 0(单堆石子不需要合并) 按区间长度从小到大计算: 先计算长度为2的区间 然后计算长度为3的区间 依此类推,直到长度为n 步骤4:寻找最优解 在所有的长度为n的区间[ i, i+n-1](0 ≤ i < n)中,找到dp[ i][ i+n-1 ]的最小值 示例演示: 假设石子堆为[ 3,4,5,2 ](环形) 步骤1:扩展数组为[ 3,4,5,2,3,4,5,2 ] 步骤2:计算各个区间的最小代价: 区间[ 0,3 ]:合并顺序3,4,5,2 区间[ 1,4 ]:合并顺序4,5,2,3 区间[ 2,5 ]:合并顺序5,2,3,4 区间[ 3,6 ]:合并顺序2,3,4,5 步骤3:比较所有可能起点的最小代价,取最小值 时间复杂度:O(n³) 需要枚举区间起点、终点和分割点 对于环形版本,需要计算2n长度的数组,但实际有效计算仍然是O(n³) 空间复杂度:O(n²) 需要维护n×n的dp表 这种方法通过环形转线性的技巧,将复杂的环形问题转化为熟悉的线性石子合并问题,是解决环形区间动态规划的经典方法。