给定一个数组,我必须找到最大阈值,以便将小于数组中元素的元素乘以c1并将大于数组中元素的元素乘以c2。
现在,我通过将数组的所有元素相加而获得的总和应该与用户给定的值相乘。
我想到了使用BST。我想不出任何主意。你能帮我一个高效的算法吗?
示例: 400、500、600 c1 = 0.05 c2 = 0.1 值:125
此处,阈值为500。 (500 + 600)* 0.1 + 400 * 0.05 = 130
答案 0 :(得分:0)
如果元素为正(或至少累计和为单调),则可以应用二进制搜索:
计算辅助数组Sums[]
中的累积总和
通过二进制搜索,找到最小的索引k
(如C ++ STL中的std::lower_bound
)
Sums[k] * c1 + (OverallSum - Sums[k]) * c2 >= Value
or
Sums[k] >= (Value - OverallSum * c2) / (c1 - c2)
请注意,第一阶段需要O(n)时间,因此对于一次任务 您可以在第二阶段使用简单的线性搜索。
但是,如果您将相同的数组与不同的Value
一起使用-二进制搜索会更有效。
这里
Sums = [400, 900, 1500]
(Value - OverallSum * c2) / (c1 - c2) =
(125 - 1500 * 0.1) / (0.05-0.1) =
-25 / -0.05 = 500
The first value in Sums[] > 500 is 900, so index is 1, value is 500