最少的交易量

时间:2018-04-27 11:22:58

标签: algorithm

我们获得了n个节点。他们每个人都有一些价值。有些不到0,有些则更高。重要的是,所有这些值的总和等于0

现在,节点号i已连接到节点i-1 mod ni+1 mod n(因此节点0已连接到n1) 。 只有连接的节点才能在它们之间进行交易事务正在从一个节点向另一个节点发送一些值 - 它可以是我们希望的任何值,当然大于0。我们需要计算所有节点的偶数值的最小事务量 - 因此在事务之后,所有节点的值都为0

有些想法如何做到这一点?

2 个答案:

答案 0 :(得分:1)

MINCOST(i,r)为将第一个 i 节点归零所需的最小事务数,发送 r (也许负)节点i权利的总值。由于节点 0 i-1 的总值必须归零,因此发送到右侧的总值也会确定发送到左侧的总值。我们会计算发送到节点 i 的权限的成本,但不计算向左发送到节点的成本 n-1

我们正在寻找的答案是所有 r 的最小 MINCOST(n,r)

x = 0 Z(x)= 0 ,否则 1

为所有 r 定义 MINCOST(0,r)= 0

我们可以计算当我们将区域向右延伸一个节点时成本如何变化:

value [i] = x 。然后:

MINCOST(i + 1,r)= MINCOST(i,r-x)+ Z(r-x)

因此,有了上述内容,就可以很容易地提出 O(N ^ 2)动态编程算法,但我们实际上可以做 O(N)< / strong>如果我们使用正确的表示法来表示 MINCOST(i,?)

的值

请注意,当我们从 i 过渡到 i + 1 时,与成本相关的值会发生变化。我们可以累积总换班而不是实际换档。除了一个特定值的成本外,所有成本都会增加。我们可以累计增加到所有成本的金额,然后记住应该减少成本的单一值。

所以对于任何 i 整个函数 r - &gt; MINCOST(i,r)可以用成本递减值的包(multiset)表示,总累积值和成本转移,我们可以在 i的每个增量的恒定时间内更新

最后,只需查找具有最大减量的值,并将减量数减去总累计成本转移,以找出将整个数组归零的最佳成本。

代码实际上比解释短得多。这是一个python实现:

def minTransactions(nodeValues):
    shift=0
    decrements={0:0}
    for nodeValue in nodeValues:
        shift+=nodeValue
        decrements[-shift] = decrements.get(-shift,0)+1
    mostdecs=-1;
    for k in decrements.keys():
        if decrements[k] > mostdecs:
            mostdecs=decrements[k]

    return len(nodeValues)-mostdecs

你可以看到它在这里运行,扩展到实际打印出交易:

https://ideone.com/gkJadt

答案 1 :(得分:-1)

如果有0个节点具有非零值,则最小事务数为0.

不可能只有1个节点具有非零值,因为总和不会为0.

如果恰好有两个节点具有非零值,则最小事务数为d,具有非零值的节点之间的最短距离(可能是顺时针方向,也可能是逆时针方向)。这是因为一个节点必须具有另一个节点值的否定值,以使总和为0,因此事务只是围绕圆圈发送值以消除其否定。

如果正好有三个节点具有非零值,那么解决方案是围绕圆圈以最短的方式发送所有正值(s)以消灭负值,并发送所有负数值围绕圆圈消灭正值的最短路径,将具有相同数量的交易,因此选择这样做的方式并不重要。实际上,将有2个节点具有一个符号(正或负)和1个具有相反符号的节点。在这里,我们必须计算它是否会节省两个节点之一将其值发送给另一个节点的时间,然后将其与自己的值捆绑在一起,或者是否将另一个方向发送到具有相反符号的节点。因此,对于这两个节点中的每一个,都有一个二进制选择要优化 - 顺时针或逆时针。

将此解决方案扩展到具有非零值的3个以上节点,留给读者练习;)