贪心算法被证明是最优的。
首先对数组进行排序,使其为[1, 1, 2, 2, 5, 5, 7, 8, 9]。然后构建三元组以最大化三元组中间的元素。第三个元素必须大于或等于中间元素,因此我们选择最大的两个值和最小的一个值。
- 最大的两个值是8和9,因此第一个三元组为1、8、9。
- 剩下的两个最大值是5和7,所以下一个三元组是1、5、7。
- 剩下的两个最大值是2和5,所以最后一个三元组是2、2、5。
这总共得到了8+5+2=15的总和。请注意,我们不需要实际产生分区;在对列表进行排序后,K个中间元素是索引为N-2、N-4、...、N-2K的元素,因此我们可以直接找到它们的总和。
[1, 1, 2, 2, 5, 5, 7, 8, 9]
↑ ↑ ↑
现在让我们证明你做不得更好。任何分区都以K个箭头指向排序数组中的元素结束。每个箭头必须与一个更大索引的非箭头配对,否则它不是三元组的中间元素,或者其三元组的第三个元素已经在另一个三元组中使用过了。因此,任何后缀数组中箭头的密度都不能超过1/2。反之,任何符合此后缀密度属性的箭头分配都可以作为一个分区实现,通过
霍尔婚姻定理。
考虑一种将箭头分配给数组索引的方法。如果出现模式↑ _ _
,则将箭头向右移动一个空格:
[..., x, y, z, ...]
... ↑ _ _ SSS
becomes
[..., x, y, z, ...]
... _ ↑ _ SSS
这不会减少箭头的数字总和,因为
x <= y
; 它除了以
y
开头的后缀外,使所有后缀的密度保持相同。 以
y
开头的后缀有 A+1 个箭头和 U+1 个非箭头,因此它的密度<= 1/2当且仅当 A+1 <= U+1。 这是因为 SSS 的密度 <= 1/2, implying A <= U。
由此可见,模式 ↑ _ ↑ _ ↑ _
无法通过将某些箭头向右移动(因为它会违反密度限制)或将某些箭头向左移动(因为它会创建 ↑ _ _
)来改进。