Arrays 创建成本最低的阵列

Arrays 创建成本最低的阵列,arrays,algorithm,data-structures,Arrays,Algorithm,Data Structures,我有一个大小为n+1的数组,其中我希望存储购买n项目的最低成本(I^th索引存储I^th项目的成本) 有m不同的卖家:每个卖家向R提供物品L(其中L,R=1和L,R您可以在这里使用某种形式的堆栈 首先,如果L相等,则按L和C描述对所有卖方进行排序 然后从第一卖方开始(与min Li) 如果堆栈是空的,把他放到堆栈中。如果没有更多的卖家 (Lj == Li) 然后cost[Li]=C[i]和Li++(堆栈中) 如果有Lj==Li的条目,则 如果RjCi跳过 如果RjCi则弹出当前卖方(i),添

我有一个大小为n+1的数组,其中我希望存储购买
n
项目的最低成本(
I^th
索引存储
I^th
项目的成本)


m
不同的卖家:每个卖家向
R
提供物品
L
(其中
L
R
=1和
L
R
您可以在这里使用某种形式的堆栈

首先,如果L相等,则按L和C描述对所有卖方进行排序

然后从第一卖方开始(与min Li)

如果堆栈是空的,把他放到堆栈中。如果没有更多的卖家

(Lj == Li)
然后
cost[Li]=C[i]
Li++
(堆栈中)

如果有
Lj==Li的条目,则

  • 如果
    Rj
    Cj>Ci
    跳过

  • 如果
    Rj
    Cj
    将此卖家添加到堆栈中

  • 如果
    Rj>Ri
    Cj>Ci
    则弹出当前卖方(i),添加此卖方(j)并添加卖方(i)


此问题是一个经典问题,您可以使用它来获得时间复杂度为O(m log n)的解决方案,以便为每个查询创建树和O(log n)

更多详情:

我们使用一棵树来表示从1到n的每个项目的最低价格

对于每个卖家,我们更新树:

tree.update(L, R, C);
tree.getMin(i, i);
最后,为了获得item
i
的最小值,我们查询树:

tree.update(L, R, C);
tree.getMin(i, i);

由于
update
getMin
都具有时间复杂度O(logn),整个程序的时间复杂度为O(max(m,n)logn)。您不需要修改原始段树实现中的任何内容。

毫无疑问,我们可以做得比O(n*m)更好,而且解决方案非常简单

以下是解决此问题的伪代码:

Construct a MIN-HEAP of the sellers based on their costs c.

Construct another array x[1...n] with its each element set to 0 initially.

Do the following initializations:
 count=0

while(count < n)
{
 S = EXTRACT_MIN(Heap)
 if(count==0)
 {            
  for(j=S.L to S.R)
  {
   leastCost[j]=S.c
   ++count
   x[j]=S.R
  } 
 }
 else
 {
  for(j=S.L;j<=S.R;++j)
  {
   if(x[j]!=0)
   {
    i=x[j] and continue;
   }
   else 
   {
    leastCost[j]=S.c
    ++count
    x[j]=S.R
   }
  }
 }
}
因此,基本上,它帮助我们直接跳转到未填充的索引

MIN-HEAP:它允许我们在时间O(logm)中找到所有成本的最小成本c

时间复杂性

由于我们访问阵列的次数最少,因此访问阵列的成本最多为n次:O(n)

构建堆需要O(m)

在最坏的情况下,所有卖家都会贡献一些指数,并且会有精确的m提取(Heap)操作,每个操作都需要O(logm)时间,所以这一操作的时间是:O(m*logm)

因此,总时间复杂度=O(n+mlogm+m)=O(n+mlogm)


顺便说一下,如果我使用C语言,我会使用Struts来卖主,如果java是一个卖家的类。请不要接受任何查询。< /P>我不知道你从哪里得到的。代码“O”(n ^ 2)< /> >。我得到O(n*m)。这完全不同。当你考虑你需要访问多少元素(从中读取),这应该是最优的。除非有任何附加信息,否则您必须从开始…我更正了它。这真的是最优的吗?即使对于非常大的n和m?我也没有其他可以添加的。@Aron太高了?是的,Aron是对的。您的卖家表有

m
卖家和
n
价格(平均值)。因此这是
n*m
。您需要至少检查每个元素一次,因此
(n*m)
是最佳选择(除非您有量子计算机)。您可以使用段树,因此创建树的时间复杂度为O(m log n),每个查询的时间复杂度为O(log n)@Gsquare最佳优化是使用我在解决方案中展示的贪婪方法。我不确定这是如何工作的。你能给出一些工作代码或更好的伪代码吗?我没有范围查询。如何为这种特殊情况构建分段树?@Gsquare:
每个卖家都提供项目L到项目R
:从L到R,向上日期值C(如果可能),这些是范围查询。对于每个项目
i
,查询是范围(i,i)的get min,其时间复杂度为O(log n).@PhamTrung请允许我澄清您的疑问。每次执行内部循环时,它都会增加控制外部循环的变量,该变量会计数。这就是我的时间复杂性的原因。@PhamTrung嵌套循环并不总是指二次时间。只有当控制内部和外部循环的变量为相互独立。我明白了,但是你如何处理这种情况?(5,5,1),(4,5,2),(3,5,3)…(1,5,5),(5,6,7)…(5,10,10)。当n=10时,每个卖家都表示为(L,R,C)。显然,总的时间复杂度将是2*(1+2+…+n/2)=O(n^2)在迭代时,您只能更新一项,但仍需要在所有范围内进行迭代。时间复杂度为2*(1+2+…+n/2)*log m=O(n^2 log m),精确到上述情况。@Phamtrong请修改您的基础知识。大O是用于渐近分析的符号,而不是您在表达式中计算的内容。