我正在创建一个简化人与人之间共享费用的计划。费用有:
捐款人必须为某项费用支付的股份不一定必须相等。经过一些任意数量的开支后,有些人会欠钱,而其他人欠钱。
问题是找到一个让所有人解决债务的简单方法。我不想让一些人付钱给其他人,而有些人根本不需要支付任何人,我希望一个人最多只需付一个人。此外,我想尽量减少一个人收到的超出他或她实际欠款的金额。例如,如果你欠100美元,你真的不想收到2000美元,并且必须向其他人转发1900美元。
每个人都有债务。债务是:
因此,该模型由一组数字组成,代表债务。
这是一种零和的情况:人们所欠的金额等于人们欠款的金额(没有贷款人就没有贷款)。这意味着无论谁收到付款,如果最后每个人都支付了欠款,就没有人欠任何钱。
Anne向Bob支付100美元。如果安妮有100的债务,她的债务现在为0.如果鲍勃的债务为-100,他的债务也是0.在该模型中,货币交易相当于从付款人的债务中扣除,并添加相同的债务相当于收件人的。
为了尽量减少交易中收款人的超额收款,我认为将最大的正债务加到每笔交易的最大负债中应该足够了。
我正在考虑为负债使用最小堆,为正债使用最大堆。然后重复执行从最大最大到最小最小的事务。这可以通过将min的键增加最大值并删除max来完成。如果债务为零,则将其从堆中删除。
让max
成为maxHeap
的最大元素,min
是minHeap
的最小元素。 max.person
和min.person
分别是max
和min
的债务人。
while(not done) do:
new transaction.from(max.person).to(min.person)
if(max + min = 0) then: //remove both
maxHeap.removeMax
minHeap.removeMin
else if (max + min < 0) then: //keep in minHeap
minHeap.increaseKey(min).by(max)
maxHeap.removeMax
else //move min to maxHeap
maxHeap.decreaseKey(max).by(|min|)
如果我没记错的话,这应该给我一个O(nlogn)的运行时间。
我的推理是否正确?根据我的问题描述,我的解决方案会得到相当好的结果吗?有没有其他人有更快和/或更简单的解决方案,仍然坚持尽可能少收到多余资金的标准?
注意:如果重要,我将用Java实现它
编辑:我发现了另一个与此非常相似的问题:Algorithm to share/settle expenses among a group。但是,它并没有解决我的问题,因为我有每个人最多一笔交易的标准。
答案 0 :(得分:2)
我已经编辑了答案,以满足一个收件人可以从多个人那里收到钱的情况,而不仅仅是来自一个人。见最下面。
有趣的问题 - 必须编码。这里是伪和数据,与Dyalog APL一样。
通常,确保最佳状态的唯一方法是使用蛮力。对于您的问题,当参与者人数约为12或更少时,这种方法很有效:
┌──┬──┬──┬──┬───┬───┬─────┬──────┬───────┬─────────┬──────────┬───────────┬─────────────┬──────────────┬─────────────────┐
│!1│!2│!3│!4│!5 │!6 │!7 │!8 │!9 │!10 │!11 │!12 │!13 │!14 │!15 │
├──┼──┼──┼──┼───┼───┼─────┼──────┼───────┼─────────┼──────────┼───────────┼─────────────┼──────────────┼─────────────────┤
│1 │2 │6 │24│120│720│5,040│40,320│362,880│3,628,800│39,916,800│479,001,600│6,227,020,800│87,178,291,200│1,307,674,368,000│
└──┴──┴──┴──┴───┴───┴─────┴──────┴───────┴─────────┴──────────┴───────────┴─────────────┴──────────────┴─────────────────┘
正如我们所见,数字因子迅速增加。如果10个参与者,它仍然是合理的360万,12个人已经是15亿。可能不值得考虑更多。
但是,如果我们谈论足够小的帮派,那么进行计算是相当微不足道的(除了一件事)。
您已设置此条件:
贡献者必须为某项费用支付的股票 不一定非得平等。
这并没有改变计算本身,但我不在这个答案如何股票结束之外。你必须有办法确定属于谁的东西。此处计算的基本要点是应付款的总和 和付款 相等。
考虑这个例子:
我们有4个人已经消耗了400美元。一个人支付了所有费用,他们决定平均分摊费用:
┌──────────┬───┬───┬───┬───┬─────┐
│Guy │1 │2 │3 │4 │Total│
├──────────┼───┼───┼───┼───┼─────┤
│Should pay│100│100│100│100│400 │
├──────────┼───┼───┼───┼───┼─────┤
│Payed │0 │0 │0 │400│400 │
└──────────┴───┴───┴───┴───┴─────┘
当1号球员支付0时,他显然需要额外支付100,等等。这是一个简单的案例。唯一的解决方案是:
1 solutions with unique transfer sums. Best solution:
┌─────────────────────────┬──────┬──────┬──────┬──────┬─────┬────────┐
│Guy # │1 │2 │3 │4 │Total│Turnover│
├─────────────────────────┼──────┼──────┼──────┼──────┼─────┼────────┤
│Should pay │100 │100 │100 │100 │400 │ │
├─────────────────────────┼──────┼──────┼──────┼──────┼─────┼────────┤
│Has paid │0 │0 │0 │400 │400 │ │
├─────────────────────────┼──────┼──────┼──────┼──────┼─────┼────────┤
│Gets from the one to left│0.00 │100.00│200.00│300.00│ │600 │
├─────────────────────────┼──────┼──────┼──────┼──────┼─────┼────────┤
│Pays to the one to right │100.00│200.00│300.00│0.00 │ │600 │
└─────────────────────────┴──────┴──────┴──────┴──────┴─────┴────────┘
请注意,表格包装 - 最左边和最右边是&#34;邻居&#34;。
我们看到每个差不多的人都会向表中的右邻居列付款,同样从他的左邻居那里得到一个。在添加他最初支付的费用,他现在得到的以及他现在支付的费用时,他最终会按照分配给他的正确总费用。
但是,如果#2支付100,而#4支付300:
┌──────────┬───┬───┬───┬───┬─────┐
│Guy │1 │2 │3 │4 │Total│
├──────────┼───┼───┼───┼───┼─────┤
│Should pay│100│100│100│100│400 │
├──────────┼───┼───┼───┼───┼─────┤
│Payed │0 │100│0 │300│400 │
└──────────┴───┴───┴───┴───┴─────┘
我们得到3个解决方案,低于最佳解决方案:
3 solutions with unique transfer sums. Best solution:
┌─────────────────────────┬──────┬──────┬──────┬────┬─────┬────────┐
│Guy # │1 │3 │4 │2 │Total│Turnover│
├─────────────────────────┼──────┼──────┼──────┼────┼─────┼────────┤
│Should pay │100 │100 │100 │100 │400 │ │
├─────────────────────────┼──────┼──────┼──────┼────┼─────┼────────┤
│Has paid │0 │0 │300 │100 │400 │ │
├─────────────────────────┼──────┼──────┼──────┼────┼─────┼────────┤
│Gets from the one to left│0.00 │100.00│200.00│0.00│ │300 │
├─────────────────────────┼──────┼──────┼──────┼────┼─────┼────────┤
│Pays to the one to right │100.00│200.00│0.00 │0.00│ │300 │
└─────────────────────────┴──────┴──────┴──────┴────┴─────┴────────┘
最糟糕的一个:
Worst solution:
┌─────────────────────────┬──────┬──────┬──────┬──────┬─────┬────────┐
│Guy # │1 │2 │4 │3 │Total│Turnover│
├─────────────────────────┼──────┼──────┼──────┼──────┼─────┼────────┤
│Should pay │100 │100 │100 │100 │400 │ │
├─────────────────────────┼──────┼──────┼──────┼──────┼─────┼────────┤
│Has paid │0 │100 │300 │0 │400 │ │
├─────────────────────────┼──────┼──────┼──────┼──────┼─────┼────────┤
│Gets from the one to left│100.00│200.00│200.00│0.00 │ │500 │
├─────────────────────────┼──────┼──────┼──────┼──────┼─────┼────────┤
│Pays to the one to right │200.00│200.00│0.00 │100.00│ │500 │
└─────────────────────────┴──────┴──────┴──────┴──────┴─────┴────────┘
上述情况更糟,因为结算付款时的总<营业额更大。你有这个标准:
我想尽量减少一个人收到的多余钱 超出他或她的实际欠款。
在大多数情况下这似乎是可能的,但我怀疑是否有任何保证。
现在考虑一下这种情况:
┌──────────┬──┬──┬──┬──┬──┬──┬──┬──┬─────┐
│Guy │1 │2 │3 │4 │5 │6 │7 │8 │Total│
├──────────┼──┼──┼──┼──┼──┼──┼──┼──┼─────┤
│Should pay│10│10│10│10│10│10│10│10│80 │
├──────────┼──┼──┼──┼──┼──┼──┼──┼──┼─────┤
│Payed │0 │0 │0 │0 │0 │0 │0 │80│80 │
└──────────┴──┴──┴──┴──┴──┴──┴──┴──┴─────┘
最佳(也是唯一)解决方案是:
1 solutions with unique transfer sums. Best solution:
┌─────────────────────────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬────────┐
│Guy # │1 │2 │3 │4 │5 │6 │7 │8 │Total│Turnover│
├─────────────────────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼────────┤
│Should pay │10 │10 │10 │10 │10 │10 │10 │10 │80 │ │
├─────────────────────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼────────┤
│Has paid │0 │0 │0 │0 │0 │0 │0 │80 │80 │ │
├─────────────────────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼────────┤
│Gets from the one to left│0.00 │10.00│20.00│30.00│40.00│50.00│60.00│70.00│ │280 │
├─────────────────────────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼────────┤
│Pays to the one to right │10.00│20.00│30.00│40.00│50.00│60.00│70.00│0.00 │ │280 │
└─────────────────────────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴────────┘
我们看到付款金额增加。尽管#7只有10的债务,但他收到60并且支付70.原因是所有其他人必须积累/积累足够的金额,以支付#8。标准是#8(以及其他每个人)只能从另一个人那里收钱,而不是从多个人那里收钱。
现在考虑一个更复杂的 - 每个都从菜单中自己做出选择。有些人为自己的食物买单,#8负责#1,#3,#5,#7和他自己的付款:
┌──────────┬──┬──┬──┬──┬──┬──┬──┬──┬─────┐
│Guy │1 │2 │3 │4 │5 │6 │7 │8 │Total│
├──────────┼──┼──┼──┼──┼──┼──┼──┼──┼─────┤
│Should pay│10│25│12│18│16│10│18│15│124 │
├──────────┼──┼──┼──┼──┼──┼──┼──┼──┼─────┤
│Payed │0 │25│0 │18│0 │10│0 │71│124 │
└──────────┴──┴──┴──┴──┴──┴──┴──┴──┴─────┘
结果非常好。那些为自己付钱的人没有受到影响:
97 solutions with unique transfer sums. Best solution:
┌─────────────────────────┬─────┬─────┬─────┬─────┬─────┬────┬────┬────┬─────┬────────┐
│Guy # │1 │3 │5 │7 │8 │2 │4 │6 │Total│Turnover│
├─────────────────────────┼─────┼─────┼─────┼─────┼─────┼────┼────┼────┼─────┼────────┤
│Should pay │10 │12 │16 │18 │15 │25 │18 │10 │124 │ │
├─────────────────────────┼─────┼─────┼─────┼─────┼─────┼────┼────┼────┼─────┼────────┤
│Has paid │0 │0 │0 │0 │71 │25 │18 │10 │124 │ │
├─────────────────────────┼─────┼─────┼─────┼─────┼─────┼────┼────┼────┼─────┼────────┤
│Gets from the one to left│0.00 │10.00│22.00│38.00│56.00│0.00│0.00│0.00│ │126 │
├─────────────────────────┼─────┼─────┼─────┼─────┼─────┼────┼────┼────┼─────┼────────┤
│Pays to the one to right │10.00│22.00│38.00│56.00│0.00 │0.00│0.00│0.00│ │126 │
└─────────────────────────┴─────┴─────┴─────┴─────┴─────┴────┴────┴────┴─────┴────────┘
然后一个案例显然好人清空了所有的口袋,并支付了124美元:
┌──────────┬──┬──┬──┬──┬──┬──┬──┬──┬─────┐
│Guy │1 │2 │3 │4 │5 │6 │7 │8 │Total│
├──────────┼──┼──┼──┼──┼──┼──┼──┼──┼─────┤
│Should pay│10│25│12│18│16│10│18│15│124 │
├──────────┼──┼──┼──┼──┼──┼──┼──┼──┼─────┤
│Payed │17│20│10│19│10│20│16│12│124 │
└──────────┴──┴──┴──┴──┴──┴──┴──┴──┴─────┘
非常好!没钱可动:
67 solutions with unique transfer sums. Best solution:
┌─────────────────────────┬────┬────┬────┬────┬─────┬─────┬────┬────┬─────┬────────┐
│Guy # │1 │3 │4 │8 │5 │6 │7 │2 │Total│Turnover│
├─────────────────────────┼────┼────┼────┼────┼─────┼─────┼────┼────┼─────┼────────┤
│Should pay │10 │12 │18 │15 │16 │10 │18 │25 │124 │ │
├─────────────────────────┼────┼────┼────┼────┼─────┼─────┼────┼────┼─────┼────────┤
│Has paid │17 │10 │19 │12 │10 │20 │16 │20 │124 │ │
├─────────────────────────┼────┼────┼────┼────┼─────┼─────┼────┼────┼─────┼────────┤
│Gets from the one to left│7.00│0.00│2.00│1.00│4.00 │10.00│0.00│2.00│ │26 │
├─────────────────────────┼────┼────┼────┼────┼─────┼─────┼────┼────┼─────┼────────┤
│Pays to the one to right │0.00│2.00│1.00│4.00│10.00│0.00 │2.00│7.00│ │26 │
└─────────────────────────┴────┴────┴────┴────┴─────┴─────┴────┴────┴─────┴────────┘
最后一个案例,所有都支付了相等的金额,但后来解决了以不同方式支付的义务:应该支付相同的费用,但支付方式不同:
┌──────────┬──┬──┬──┬──┬──┬──┬──┬──┬─────┐
│Guy │1 │2 │3 │4 │5 │6 │7 │8 │Total│
├──────────┼──┼──┼──┼──┼──┼──┼──┼──┼─────┤
│Should pay│10│10│10│10│10│10│10│10│80 │
├──────────┼──┼──┼──┼──┼──┼──┼──┼──┼─────┤
│Payed │7 │20│10│5 │10│10│6 │12│80 │
└──────────┴──┴──┴──┴──┴──┴──┴──┴──┴─────┘
微小的营业额:
54 solutions with unique transfer sums. Best solution:
┌─────────────────────────┬────┬────┬────┬─────┬─────┬────┬────┬────┬─────┬────────┐
│Guy # │1 │8 │7 │4 │2 │3 │5 │6 │Total│Turnover│
├─────────────────────────┼────┼────┼────┼─────┼─────┼────┼────┼────┼─────┼────────┤
│Should pay │10 │10 │10 │10 │10 │10 │10 │10 │80 │ │
├─────────────────────────┼────┼────┼────┼─────┼─────┼────┼────┼────┼─────┼────────┤
│Has paid │7 │12 │6 │5 │20 │10 │10 │10 │80 │ │
├─────────────────────────┼────┼────┼────┼─────┼─────┼────┼────┼────┼─────┼────────┤
│Gets from the one to left│0.00│3.00│1.00│5.00 │10.00│0.00│0.00│0.00│ │19 │
├─────────────────────────┼────┼────┼────┼─────┼─────┼────┼────┼────┼─────┼────────┤
│Pays to the one to right │3.00│1.00│5.00│10.00│0.00 │0.00│0.00│0.00│ │19 │
└─────────────────────────┴────┴────┴────┴─────┴─────┴────┴────┴────┴─────┴────────┘
正如我们通过蛮力所做的那样,它意味着产生参与者数量的所有权利。这可能是棘手的部分。例如,(1,2,3,4)的所有排列都在下面(逐列编写,以提高可读性):
1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 4
2 2 3 3 4 4 1 1 3 3 4 4 1 1 2 2 4 4 1 1 2 2 3 3
3 4 2 4 2 3 3 4 1 4 1 3 2 4 1 4 1 2 2 3 1 3 1 2
4 3 4 2 3 2 4 3 4 1 3 1 4 2 4 1 2 1 3 2 3 1 2 1
你最好搜索这一代。如果它在一个循环中发生就没问题。关键是你可以访问一列(如果行是行,则可以是行)。
伪:
// NOTE: The data is written as arrays
// For example "0 0 0 0" implies a 4-element array (vector) of integers
// Of course there may be other number of participants ("guys"),
// then we need "other-element" arrays, for example 7-element ones
// The code below may require additional looping
ToPay = 100 100 100 100 // Topmost example in this answer
HasPayed = 0 0 0 400 // Ditto
// Calculate debt
// This probably requires a loop from 1...4
Debt[n] = ToPay[n] - HasPayed[n] // Debt is now: 100 100 100 -300
smallest = 9999999 // Sufficiently big initial value
:For Row :In [each permutation of (1 2 3 4) // Row is now for example: 2 4 3 1
Test = Debt[Row] // Test is now for example: 100 -300 100 100
Accu = [4-element vector of zeroes]
Accu[1] = Row[1]
minimum = Row[1]
s = 2
:Repeat
Accu[s] = Accu[s-1] + Row[s]
minimum = min(minimum, Accu[s]) // We simply grab the smalles element in Accu
s += 1
:Until (s > 4)
// As this is ready, Accu may contain eg. 100 -200 -100 0
// and minimum would then contain -200
sum = 0
t = 1
:Repeat
Accu[t] -= minimum
sum += Accu[t]
t += 1
:Until (t > 4)
// When ready, Accu would be eg. 300 0 100 200
// and sum would be 300+0+100+200, ie. 600
:If (sum < smallest)
[store Row as best so far, for example into "BestRow"]
[store Accu, for example into BestAccu"]
smallest = sum
:End
:End
现在
可以采用其他标准来实现最好的方式&#34;但是这个解决方案可以最大限度地减少金钱的流动并且#34;并保持交易每人一次付款。
另外需要注意的是,有多种最佳解决方案&#34;,其中一种排列产生与另一种排列相同的最小周转率。对于最后一个例子,同样好的解决方案的数量(最好到最差)是:
48 96 144 144 240 240 480 336 672 432 768 912 960 768 1296 864 1392 1104 1200 1056 1488 1488 1488 1200 1344 1152 1776 1056 1344 1056 1152 1152 1344 768 1104 768 1056 720 912 480 672 528 528 240 576 288 432 192 288 144 240 48 96 48
...意思是48&#34;最佳解决方案&#34;,96&#34;第二好&#34;等
编辑:
我被告知一个我不正常地假设的标准:一个人只能从另一个人那里收钱。情况并非如此,任何人都可以向其他人提供资金,但可以从任何人,一个人或多人<接收资金。
事实证明,上面给出的解决方案已经基本完成了。要解决这个新情况,只需要再处理一下结果。也就是说,现在存在于上述逻辑中的累积,其中连续多个人可能积累越来越多的钱,同时他们自己有助于积累,以便向付了大笔钱的人付出代价(&#34;先生X&#34;) - 需要拆除这种累积,以便它的累积部分直接>>支付给X,而不是通过其他参与者。
考虑这种情况:
┌──────────┬──┬──┬──┬──┬──┬──┬─────┐
│Guy │1 │2 │3 │4 │5 │6 │Total│
├──────────┼──┼──┼──┼──┼──┼──┼─────┤
│Should pay│10│10│20│30│10│20│100 │
├──────────┼──┼──┼──┼──┼──┼──┼─────┤
│Payed │35│0 │25│0 │0 │40│100 │
└──────────┴──┴──┴──┴──┴──┴──┴─────┘
虽然看起来很简单,但通过头部计算很难解决,因为它是循环的。通过早期的方法,我们得到了&#34;累积&#34;回答:
22 solutions with unique transfer sums. Best solution:
┌─────────────────────────┬──┬──┬──┬──┬──┬──┬─────┬────────┐
│Guy # │1 │3 │2 │5 │6 │4 │Total│Turnover│
├─────────────────────────┼──┼──┼──┼──┼──┼──┼─────┼────────┤
│Should pay │10│20│10│10│20│30│100 │ │
├─────────────────────────┼──┼──┼──┼──┼──┼──┼─────┼────────┤
│Has paid │35│25│0 │0 │40│0 │100 │ │
├─────────────────────────┼──┼──┼──┼──┼──┼──┼─────┼────────┤
│Gets from the one to left│30│5 │0 │10│20│0 │ │65 │
├─────────────────────────┼──┼──┼──┼──┼──┼──┼─────┼────────┤
│Pays to the one to right │5 │0 │10│20│0 │30│ │65 │
└─────────────────────────┴──┴──┴──┴──┴──┴──┴─────┴────────┘
然后我们可以解决每一个的债务,这是第二行 - 第三行(债务为正):
┌───┬──┬──┬──┬───┬──┐
│-25│-5│10│10│-20│30│
└───┴──┴──┴──┴───┴──┘
使用它,我们可以解决一些名为&#34;积累 - 这是第五行 - 债务:
┌──┬─┬─┬──┬──┬─┐
│30│5│0│10│20│0│
└──┴─┴─┴──┴──┴─┘
由此,我们可以解决哪些付款可以从&#34;付款到正确的&#34;一个&#34;付钱的人#n&#34; - 这只是通过比较累积的对,并将累积的最后一个元素与第一个元素进行比较(因为这个问题是循环的)。第一个比较是(30 <5),然后是(5 <0),然后是(0 <10)等;最后一个是(0 <30):
┌─┬─┬─┬─┬─┬─┐
│0│0│1│1│0│1│
└─┴─┴─┴─┴─┴─┘
1表示下一次累积大于当前累积 - 这些是现在可直接转入#n的付款。
谁是#n? #n 是一系列之后的下一个人。插槽3和插槽4(上面第一个答案中的#2和#5)后面是第6个人 - 他是#2和#5现在支付的那个,而其他支付保持不变。
这个编码不是很棘手,但是依赖于语言,因此我将其留给实现者。只需在每组中向前推进累积,直到(并包括)一组之后的每个零,并重新解决付款问题。答案很好:
┌──────────┬──┬──┬──┬──┬──┬──┐
│Guy │1 │3 │2 │5 │6 │4 │
├──────────┼──┼──┼──┼──┼──┼──┤
│Should pay│10│20│10│10│20│30│
├──────────┼──┼──┼──┼──┼──┼──┤
│Payed │35│25│0 │0 │40│0 │
├──────────┼──┼──┼──┼──┼──┼──┤
│Pays to │3 │ │6 │6 │ │1 │
├──────────┼──┼──┼──┼──┼──┼──┤
│Amount │5 │ │10│10│ │30│
└──────────┴──┴──┴──┴──┴──┴──┘
答案很有意思,因为那个#1,实际上是一个超额预算的人,必须向3号人支付5美元。发生这种情况是因为#4(最右边)的债务为30,他必须向另一个人支付 - 这会导致超额支付&#34;到#1,但作为#1的邻居#3需要从某个地方获得5,#1传递给他。然后其余部分完美契合,#6从#2和#5获得20。标准是尽量减少付款并找到最佳解决方案,对吧? : - )
一些例子(情况和解决方案)。低于2的同等付款人:
┌──────────┬──┬──┬──┬─┬─┬──┬──┬──┬─────┐ ┌───────┬─┬─┬──┬──┬─┬─┬──┬──┐
│Guy │1 │2 │3 │4│5│6 │7 │8 │Total│ │Guy │1│5│6 │8 │2│4│7 │3 │
├──────────┼──┼──┼──┼─┼─┼──┼──┼──┼─────┤ ├───────┼─┼─┼──┼──┼─┼─┼──┼──┤
│Should pay│7 │11│13│8│5│10│12│14│80 │ │Pays to│ │2│2 │2 │ │1│1 │1 │
├──────────┼──┼──┼──┼─┼─┼──┼──┼──┼─────┤ ├───────┼─┼─┼──┼──┼─┼─┼──┼──┤
│Payed │40│40│0 │0│0│0 │0 │0 │80 │ │Amount │ │5│10│14│ │8│12│13│
└──────────┴──┴──┴──┴─┴─┴──┴──┴──┴─────┘ └───────┴─┴─┴──┴──┴─┴─┴──┴──┘
一个大的和一些小的付款人:
┌──────────┬──┬───┬──┬──┬──┬──┬──┬──┬──┬──┬─────┐ ┌───────┬─┬──┬──┬──┬──┬──┬──┬─┬──┬─┐
│Guy │1 │2 │3 │4 │5 │6 │7 │8 │9 │10│Total│ │Guy │1│3 │7 │4 │10│6 │8 │2│5 │9│
├──────────┼──┼───┼──┼──┼──┼──┼──┼──┼──┼──┼─────┤ ├───────┼─┼──┼──┼──┼──┼──┼──┼─┼──┼─┤
│Should pay│10│10 │10│12│10│19│11│33│6 │12│133 │ │Pays to│2│2 │2 │2 │2 │2 │2 │ │9 │1│
├──────────┼──┼───┼──┼──┼──┼──┼──┼──┼──┼──┼─────┤ ├───────┼─┼──┼──┼──┼──┼──┼──┼─┼──┼─┤
│Payed │5 │112│0 │0 │0 │1 │0 │0 │15│0 │133 │ │Amount │6│10│11│12│12│18│33│ │10│1│
└──────────┴──┴───┴──┴──┴──┴──┴──┴──┴──┴──┴─────┘ └───────┴─┴──┴──┴──┴──┴──┴──┴─┴──┴─┘
非常不规律:
┌──────────┬──┬──┬──┬──┬──┬──┬──┬──┬─┬──┬─────┐ ┌───────┬──┬──┬─┬─┬─┬─┬─┬──┬──┬─┐
│Guy │1 │2 │3 │4 │5 │6 │7 │8 │9│10│Total│ │Guy │1 │10│4│9│5│3│6│7 │8 │2│
├──────────┼──┼──┼──┼──┼──┼──┼──┼──┼─┼──┼─────┤ ├───────┼──┼──┼─┼─┼─┼─┼─┼──┼──┼─┤
│Should pay│10│10│5 │12│10│19│11│33│6│12│128 │ │Pays to│10│ │9│5│3│ │2│2 │2 │ │
├──────────┼──┼──┼──┼──┼──┼──┼──┼──┼─┼──┼─────┤ ├───────┼──┼──┼─┼─┼─┼─┼─┼──┼──┼─┤
│Payed │7 │50│10│10│6 │12│1 │10│7│15│128 │ │Amount │3 │ │2│1│5│ │7│10│23│ │
└──────────┴──┴──┴──┴──┴──┴──┴──┴──┴─┴──┴─────┘ └───────┴──┴──┴─┴─┴─┴─┴─┴──┴──┴─┘
正如我们所见,解决方案看起来非常理想。