请问有人是否已经看到或遇到过以下问题?
我需要处理成本/利润值列表 c 1 / p 1 ,c 2 / p 2 ,c 3 / p 3 ,...满足:
这是一个示例:2/3
,4/5
,9/15
,12/19
如果有人尝试
要插入 10/14
在上面的列表中,操作被拒绝因为现有
成本/利润对9/12
:增加成本永远不会有用(9->10
)
并减少利润(14->12
)。例如,此类列表可能出现在
(状态)背包问题的动态编程算法,其中
成本可以代表权重。
如果在上面的列表中有一个插入 7/20
,则应该触发9/15
和12/19
的删除。
我使用C++
std::set
编写了一个解决方案(通常用
红黑树),但我需要提供最终的比较功能
变得有点过于复杂。而且,插入这样的集合需要
对数时间,这很容易实际导致线性时间(就其而言
非摊销的复杂性)例如当插入触发所有其他的删除时
元素。
我想知道是否存在更好的解决方案,因为有无数的解决方案 实现(有序)集合,例如,优先级队列,堆,链表,散列 桌等等。
这是一个帕累托前线(obj1:最低成本,obj2:最大利润),但我仍然找不到记录它的最佳结构。
答案 0 :(得分:0)
我没有完全理解你描述的规则,因此我会非常地说,尝试插入可能会触发拒绝,如果被接受,则需要删除后续项目。
您需要使用平衡比较树,表示为数组。在这种情况下,找到所需的节点将花费O(logN)时间,这将是搜索或拒绝插入尝试的复杂性。当您需要删除项目时,然后删除它们并插入一个新的项目,其复杂性为
O(logN + N + N + logN)(即搜索,删除,重新平衡和插入。如果重新平衡我们知道要插入新项目的位置,我们可以摆脱最后的对数)
O(logN + N + N + logN)= O(2logN + 2N)= O(logN ^ 2 + 2N),这在很大程度上是线性复杂度。