【问题标题】:Maximize product of numbers最大化数字的乘积
【发布时间】:2018-10-29 00:52:54
【问题描述】:

给定一个数字n 和分区值k,这样n1+n2+..nk=n,我需要找到集合{n1,n2..,nk},这样n1*n2*...nk 是最大的。

解决此问题的一种方法是列出所有子集,然后找到具有最大乘积的子集。是否有任何有效的算法(比蛮力更好的算法)?

要查找子集,可以使用这个公式,我目前正在使用this 逻辑进行开发。

【问题讨论】:

  • k 子集是什么? n1,n2,...nk 是您拥有的某个子集的一部分吗?或者你可以“发明”它们?
  • 对它们进行排序,将最大的k 相乘。如果你必须处理负数,它会变得有点复杂,但只是一点点。
  • @amit 对不起,没有k 子集。我的意思是子集{n1,...nk} 的所有可能子集。
  • 我仍然对问题描述感到困惑,抱歉。您有一些数字,您需要选择其中的一个子集,它 (a) 满足某些要求并且 (b) 最大化某些目标函数。我认为要求 (a) 是子集必须总和为给定的数字,即 n——但不清楚子集是否需要精确包含一些给定的 k 个数字。
  • @j_random_hacker 你有一个号码n。您需要找到k 数字,使得它们的总和等于n,并且这些k 数字的乘积是您可以找到的所有k 数字集合中最大的。

标签: algorithm math


【解决方案1】:

最大化乘积n1*n2*..*nk等价于最大化其对数log(n1*n2*..*nk) = log(n1)+log(n2)+ .. +log(nk),受限于n1+..+nk = n

因为对数是一个凹函数,这个最大值将在 k-uplets 上达到,这样没有两个值相差超过两个(因为log((a+b)/2) >= (log(a)+log(b))/2。这意味着,定义x = floor(n/k),你可以限制自己对于每个n_i 都属于{x,x+1} 的情况。

这进一步意味着您可以准确地确定子集:如果您让a 满足a*x+(k-a)*(x+1) = n,那么最大子集将是
n1 = x, n2 = x, .., n_a = x, n_{a+1} = x+1, .., nk = x+1.
a 上的方程可以显式求解并产生 a = k*(ceil(n/k))-n

【讨论】:

    【解决方案2】:

    这是我现在的一个想法。

    如果数字是n,并且它可以被k 整除,那么我们就有n/k 出现k 次,这使得求和的条件有效。另外,请注意,在这种情况下,当我们使用 n/k 时,k 完美地除以 n,结果相乘的结果将是最大的。如果它不是一个完美的除数,那么我们可以找到ceil(n/k)*k并乘以ceil(n/k)k-1,最后一个整数可以通过n - (ceil(n/k) * (k-1))找到。

    假设n_i 的值可以相同。

    编辑

    我有一些非常糟糕的数学,但这里有一个证明为什么要使 n1n2 必须相等,因为 n1 * n2A = n1 + n2 时最大。

    A = n1 + n2 n2 = A - n1; P = n1 * n2 P = n1 * (A - n1) = A * n1 - n1^2 P 对 n1 微分 dP/dn1 = A - 2 * n1 为了找到拐点,我们做 dP/dn1 = 0 并求解 A - 2 * n1 = 0 n1 = A/2 这表明 n1 = A/2,因此 n1 = n2 这告诉使 P 最大(因为双微分是负的),我们需要 n1 = n2

    我认为这个证明可以扩展到k 变量?也许有人可以扩展这个答案。

    【讨论】:

    • @AnindyaDutta:还在考虑这个。我认为这应该可以正常工作。但在给出数学证明之前,答案是不完整的。
    • 是的,这工作正常。我也在寻找数学证明。也许我应该把这个问题转移到数学 stackexchange。
    • @AnindyaDutta,不确定是否要移动或发布特定问题(如果它已经不存在)。但我认为在这个答案中为多变量扩展上述证明可能会让你有所收获。
    • 证明只是从日志的凹度得出的。无需区分(见我的回答)。
    • @vib:是的,花了一点时间才得到它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 2014-02-27
    • 1970-01-01
    • 2013-12-31
    • 2021-08-21
    • 2014-01-31
    相关资源
    最近更新 更多