当前位置: 首页 > 知识库问答 >
问题:

找到一个最小化总和的排列

黄兴业
2023-03-14

我有一个元素数组< code>[(A1,B1),...,(An,Bn)](都是正浮点和Bi

毫无疑问,我可以尝试所有这些方法,并选择一个给出最小和的方法(这将给出正确的结果O(n!)).

我尝试将总和更改为A1 B1*(A2 B2*(A3 B3*(… B(n-1)*AN))并尝试使用贪婪算法,该算法在每个步骤上获取最大的Ai元素(这不会产生正确的结果)。

现在,当我看最新的方程时,我觉得这里我看到了最优子结构A(n-1)B(n-1)*An,因此我必须使用动态编程,但我无法找出正确的方向。有什么想法吗?

共有1个答案

欧阳君浩
2023-03-14

我认为这可以在O(N log(N))中解决。

任何置换都可以通过交换相邻元素对来获得;例如,这就是气泡排序工作的原因。因此,让我们看看交换条目(a[i],B[i])(a[i 1],B[1])的效果。我们想知道在哪些情况下进行这种交换是一个好主意。这仅对ith和i1th项有效,所有其他项保持不变。此外,在交换之前和之后,这两个术语都有一个因子B[1]*B[2]*…*B[i-1],我们现在可以称其为CC是正数。

在交换之前,我们正在处理的两个术语是 C*A[i] C*B[i]*A[i 1],之后它们是 C*A[i 1] C*B[i 1]*A[i]。如果两者之间的差异为正,则这是一个改进:

C*(A[i] + B[i]*A[i+1] - A[i+1] - B[i+1]*A[i]) > 0

由于C是正的,我们可以忽略该因素,只查看As和Bs。我们得到

A[i] - B[i+1]*A[i] > A[i+1] - B[i]*A[i+1]

或者等同地

(1 - B[i+1])*A[i] > (1 - B[i])*A[i+1]

这两个表达式都是非负的;如果< code>B[i]或< code>B[i 1]中的一个是1,则包含“1减去该变量”的项是0(因此,如果< code>B[i]是1,我们应该交换,但如果< code>B[i 1]是1,则不交换);如果两个变量都是一,那么两项都是零。现在让我们假设两者都不等于一;然后我们可以进一步重写以获得

A[i]/(1 - B[i]) > A[i+1]/(1 - B[i+1])

因此,我们应该计算这两项的表达式< code>D[i] := A[i]/(1 - B[i]),如果左边的大于右边的,就交换它们。在这种情况下,我们可以通过将< code>D[i]定义为无限大,将这种情况扩展到一个或两个< code>B为一的情况。

好的,让我们回顾一下-我们发现了什么?如果存在一对ii 1,其中

计算所有D[i]值可以在一次线性时间内完成。排序可以使用O(N log(N))算法完成(我们只需要将相邻元素的交换作为参数/证明,以表明这是最佳解决方案,而不是实现的一部分)。

 类似资料:
  • 我有一个数组(自然数),我需要构建一个贪婪的算法,找到1…n的排列(i1,…in),使和最小:。 当然,我可以尝试所有这些,并选择一个给出最小的总和(这将在O(n!)中给出正确的结果)。 我贪婪的选择是按降序选择数字,但我不知道如何证明这是有效的。 页(page的缩写)这只是为了学习和训练,我不能“贪婪地”思考

  • 我试图在N大小的数组的k个元素中找到最小和次最小的元素(没有排序和最小/最大堆)。 使用传统的方法,首先从第< code>0个元素开始,在第< code>k个元素中找到最小的和第二小的元素,然后将起始点移动< code>1并重复该过程。但是它的复杂度是< code>O(Nk)。如果可能,我需要一个复杂度为< code>O(N)的解决方案。对此有什么建议吗? 在Jubobs的注释后编辑:例如,如果s

  • 这一次我的头撞到了墙上。。。希望能得到一些帮助。 我将在下面用模拟数据解释一个例子,但本质上,我试图在其他变量的多个组合中最小化列的总和。 问:在每个和中,通过查看和中跑步者的不同组合,让中的所有跑步者完成比赛()的最快方法是什么? 下面数据集的每一行代表一场比赛的完整“跑步”。变量包括: 出发时团队跑步者:这一行数据中跑步和计时的人 建立一个故事:假设我有关于一个跑步团队成员的不同组合完成一次试

  • 我在想一个算法来解决下面的问题: 问题是如何找到最小的边数来满足所有客户的要求? 有一个简单的例子: 客户1希望从顶点a到顶点B。 客户2希望从顶点b到顶点C。 客户3希望从顶点a到顶点C。 null

  • 这是我的算法。 我做了一个。每次当我找到时,我都知道我得到了一个有向循环。 然后我将暂时沿着向后(直到我在循环中遍历所有顶点),并计算。 我的算法正确吗? 如果我的算法正确,时间复杂度是多少? 这个问题有没有更好的算法?

  • 如何在数据集中找到几个最小值中的第一个?我希望至少2大于最小值。 例如, 我想将df['value'][0]或者简单地说(0.6)标识为这个数组中的第一个最小值。然后将df[‘值’][4]或(2.8)确定为至少比第一个确定的最小值(0.6)大2的值。 这适用于其他数据集,但在最小值为第一个时不适用。 理想的输出是: 正如评论中建议的那样,循环将是更好的方法。