N 个人需要以下方式提供的不同金额的货币: X_i (1 <= i <= N) 但是我们有一个固定的货币,用 M 表示。 M可能少于满足每个人的需求所需的总金额。
我想找到一种分配货币(M)的方法,以使所需货币与给定货币之间的最大差额在所有人员中最小化。有办法吗?
e.g : N = 4, M=3
X1=5, X2=4, X3=2, X4=2
In this case we should distribute like : 2 1 0 0
so difference array is : 3 3 2 2
maximum difference is minimized (which is 3)
也欢迎与此主题相关的任何有趣链接。
答案 0 :(得分:1)
这可以在逐步降低债务金额后一次解决。债务是自上而下支付的。这段python代码应该很清楚:
def get_max_debt_after_distribution(debt, money):
if not debt:
raise ValueError('Please specify debt')
debt.sort(reverse=True)
debt.append(0) # Add zero debt to simplify algorithm
for i in range(1, len(debt)):
last_amount = debt[i-1]
new_amount = debt[i]
# To bring the max diff down from "last_amount" to "new_amount",
# we need to pay the difference for each debt
to_pay = (last_amount - new_amount) * i
# Check if we have enough money to pay the full amount
if to_pay <= money:
money -= to_pay
else:
# Out of money. Remaining money goes to highest debts.
return last_amount - int(money / i)
# There was enough money to pay all the debt
return 0
print(get_max_debt_after_distribution([5, 4, 2, 2], 3)) # prints 3
print(get_max_debt_after_distribution([5, 5, 5, 5], 7)) # prints 4
答案 1 :(得分:0)
这可以通过贪婪的方法解决。
首先,请注意,初始所需金额也是所需款项与给定金额之间的初始差额(因为您给了每个人0)。因此,在您的示例中,差异从[5,4,2,2]开始。
第二,请注意,在给定的时间内将钱捐给除了拥有最大差额的人以外的任何人都不会减少最大差额。例如,如果数组为5、4、2、2,则向除第一人以外的任何人捐钱不会减少最大差额:[5、3、2、2],[5、4、1、2 ],[5,4,2,1](最大差异保持在5)。
因此,在给定点上具有最大差异的人(或任何领带,如果有平局)时,应始终给一枚硬币,直到用尽硬币:[5、4、2、2 ]-> [4,4,2,2]-> [3,4,2,2]-> [3,3,2,2]-> [2,3,2,2]-> [2, 2,2,2],等等。
当然,在实施算法时,实际上并不需要一一给予硬币,但这是您应该做什么的基本思路。