查找每个商店的间隔

时间:2019-03-21 03:40:48

标签: algorithm

您在一行中有n个商店,每个商店都有相关的金额$ c_i $。在时间1,您从商店1开始。在随后的每个时间,您可以选择访问商店i-1,停留在商店i或访问商店i + 1。无论您访问过该商店多少次,您都可以在每个时间步骤中假设自己在商店i中收集$ c_i $的钱。

给出一次$ t_j $的时间列表,找到可以在$ t_j $个时间步长内收集钱的情况下可以收集的最大金额。

我在想办法预处理数据时遇到了麻烦。我的想法是,对于每个展位,我想找到一个时间间隔,在该时间间隔内,最好直接赶到那个展位并停留在那儿,在每个时间步骤都收钱。我不确定在O(n)时间还是O(nlogn)时间有效地执行此操作的正确方法。

编辑:我目前正在为每个摊位做一个工作,我有一个随时间变化的表达式,表示如果我直接去展位并呆在那里,我可以收取的最大金额。然后每次,我都将所有这些功能发挥到最大。这需要线性时间来处理每次查询。我想要一个对数的方法。

1 个答案:

答案 0 :(得分:0)

您直接通过前往商店i并在给定的总时间t停留在商店中来返回金额的收益函数是

r_i(t) = sum(j from 1 to i - 1: c_j) + c_i * (t - i + 1)

每个i的总和可以递增计算,您会得到一个整齐的线性函数:

r_i(t) = a_i + b_i * t

带有a_i = sum as above + (1 - i) * c_ib_i = c_i

现在,对于每次t,您要查找所有r_i(t)中的最大值。为此,我们可以使用功能的排序。具体来说,如果函数f1在其交点之前大于f2,我们可以对它们进行排序,以使函数f1早于f2出现。然后,如果我们具有给定点t的可用功能(在r_i中可以到达的所有t),我们只需要逐步执行有序序列即可。对于开始时间,第一个元素将是最佳功能。然后,我们可以使用下一个功能检查交点。如果t在该交点之后,我们将继续执行此功能,因为这将是当前间隔的新最大值。等等。如果您按时间对查询进行排序,则可以针对每个查询以增量方式完成此操作。在执行此过程时,您还需要添加可用的新功能。使用适当的数据结构(例如,二进制搜索树),您可以在O(log n)中进行插入。

那么,我们如何比较两个函数f1(t) = a1 + t * b1f2(t) = a2 + t * b2?相交点为ti = (a2 - a1) / (b1 - b2)。如果f1,则f2大于b1 < b2

这是整体算法:

input: n stores, q queries Q
sort queries by time - O(q log q)
create empty BST
currentBestFunction = empty  //pointer to element in BST
nextQuery = Q.first
sumCi = 0   //temporary variable for incremental sum
for t = 1 to maxQ
    if t <= n
        // we can reach a new store
        a = sumCi + (1 - t) * c_t
        b = c_t
        sumCi += c_t
        insert function (a, b) into BST - O(log n)
    if currentBestFunction = empty
        currentBestFunction = the inserted function
    while currentBestFunction is not the last function in BST
        successor = find successor function to currentBestFunction in BST
        calculate intersection ti = (successor.a - currentBestFunction.a) / (currentBestFunction.b - successor.b)
        if ti > t
            break //we are in the interval for the current best function
        else
            currentBestFunction = successor
    loop
    if nextQuery == t
        answer query by evaluating currentBestFunction at t
        advance nextQuery
        if no more queries then stop