You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:求最小化总代价的序列中间元素删除O(n³)复杂度算法

高效解法:区间动态规划(O(n³) 时间复杂度)

嘿,这个问题其实是经典的区间动态规划场景,暴力枚举删除顺序的阶乘级复杂度肯定没法处理稍大的n,咱们直接用DP来解决,正好能达到你要的O(n³)时间复杂度。我给你一步步拆解思路:

1. 先明确DP状态的定义

咱们定义 dp[i][j] 表示删除区间 [i, j] 内所有中间元素(最终只保留 a[i] 和 a[j])时的最小总代价。这里有几个边界情况:

  • 如果 i == j:没有元素可删,代价为0
  • 如果 j == i+1:中间没有元素,代价也为0

2. 推导状态转移方程

核心思路是:对于区间 [i, j],咱们假设最后一个被删除的元素是 k(i < k < j)。这时候,当把 [i,k] 和 [k,j] 内的中间元素都删完后,k 的左右邻居就只剩下 a[i] 和 a[j] 了,所以删除 k 的代价就是 a[i] * a[j]。

那整个区间 [i,j] 的最小代价,就是处理 [i,k] 的最小代价 + 处理 [k,j] 的最小代价 + 删除 k 的代价。所以转移方程是:

dp[i][j] = min(dp[i][k] + dp[k][j] + a[i] * a[j]) ,其中 i < k < j

3. 初始化与计算顺序

  • 初始化:所有 dp[i][i] = 0,dp[i][i+1] = 0,这些都是无需删除元素的情况。
  • 计算顺序:必须按区间长度从小到大计算。因为长区间的解依赖于更短的子区间解,所以我们从长度为3的区间开始(长度1、2的已经初始化),直到覆盖整个序列的长度n。

举个直观的小例子

比如序列 A = [1,2,3,4],我们要算 dp[0][3](假设数组是0索引):

  • 可选的k是1和2:
    • 当k=1时:dp[0][1] + dp[1][3] + 1*4 = 0 + (dp[1][2]+dp[2][3]+2*4) +4 = 0 + (0+0+8)+4 = 12
    • 当k=2时:dp[0][2] + dp[2][3] +1*4 = (dp[0][1]+dp[1][2]+1*3)+0+4 = (0+0+3)+4 =7
      所以 dp[0][3] = min(12,7) =7,这就是删除所有中间元素的最小总代价。

复杂度验证

  • 区间长度有O(n)种(从3到n)
  • 每个长度对应的起始点i有O(n)种选择
  • 每个区间 [i,j] 对应的k有O(n)种可能
    三者相乘就是O(n³),完全符合你的要求。

伪代码实现参考

n = len(A)
# 初始化n×n的DP数组,默认值为0
dp = [[0]*n for _ in range(n)]

# 遍历区间长度,从3开始到n
for length in range(3, n+1):
    # 遍历所有可能的起始索引i
    for i in range(n - length + 1):
        j = i + length - 1
        dp[i][j] = float('inf')  # 先设为无穷大,再找最小值
        # 遍历所有可能的最后删除元素k
        for k in range(i+1, j):
            current_cost = dp[i][k] + dp[k][j] + A[i] * A[j]
            if current_cost < dp[i][j]:
                dp[i][j] = current_cost

# 最终答案就是删除整个序列中间元素的最小代价
print(dp[0][n-1])

这个方案的核心是把大问题拆解成子区间的最优解,用DP缓存结果避免重复计算,比暴力解法高效太多,完全能处理中等规模的n值。

内容的提问来源于stack exchange,提问作者Avaneesh Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:01:05