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

求解包含列表所有元素的最少递增序列数(可从两端构建)

解决思路:混合左向/右向递增序列的最少划分问题

首先明确核心规则:

  • 左向递增序列:元素按原列表顺序排列,每个后续元素比前一个大
  • 右向递增序列:元素按原列表逆序排列(从右往左取元素),每个后续元素(原列表中更靠左的元素)比前一个大(对应原列表中该序列是递减的)

我们的目标是用最少的左向+右向序列组合覆盖所有元素,且无重复元素。


步骤1:利用已生成的序列集合找最优组合

你已经得到了两个方向的极大覆盖序列:

  • left_to_right(原列表的极大左向递增序列):[[1,2,3,4,8],[7], [6]]
  • right_to_left(反转列表的极大递增序列,对应原列表的极大右向递增序列):[[6,7,8], [4], [3], [2], [1]]

这些序列是各自方向上能覆盖最多元素的"最大"序列,我们可以通过组合两个方向的序列,避免元素重复覆盖来找到最优解:

具体操作示例

  1. 优先选择覆盖元素最多的左向序列:[1,2,3,4,8],它覆盖了{1,2,3,4,8}五个元素
  2. 剩余未覆盖元素是{7,6},在right_to_left中找到包含这两个元素的序列[6,7,8],去掉已覆盖的8后,得到右向序列[6,7],正好覆盖剩余元素
  3. 最终组合为[[1,2,3,4,8], [6,7]],总序列数为2,即最优解

同理,也可以先选右向序列[6,7,8],再用左向序列[1,2,3,4]覆盖剩余元素,结果一致。


步骤2:通用化解法(适用于任意长度列表)

如果列表更长,我们可以用枚举+贪心的思路来系统求解:

  1. 枚举左向序列的所有子集:每个子集对应一组左向序列的组合,计算该组合覆盖的元素集合
  2. 计算剩余元素的最少右向序列数:对于每个左向子集,找出覆盖剩余元素所需的最少右向序列数量(可通过贪心算法:优先选覆盖剩余元素最多的右向序列)
  3. 记录最小总序列数:遍历所有左向子集,取「左向序列数+右向序列数」的最小值
  4. 反向验证:同理枚举右向序列子集,再找对应左向序列数,确保没有遗漏更优解

对于短列表(如你的示例长度为7),左向序列只有3个,子集总数仅为8种,计算成本极低。


步骤3:贪心优化(避免枚举所有子集)

如果列表长度较大,枚举所有子集效率太低,可以用以下贪心策略快速逼近最优解:

  1. 维护两个集合:
    • covered:已被覆盖的元素集合
    • used_sequences:已选中的序列列表
  2. 循环执行以下操作,直到covered包含所有元素:
    a. 在左向序列中选未使用过、覆盖未被覆盖元素最多的序列,加入used_sequences,并更新covered
    b. 在右向序列中选未使用过、覆盖未被覆盖元素最多的序列,加入used_sequences,并更新covered
  3. 最终used_sequences的长度就是近似最优解,对于大多数场景已经足够准确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:37:50