使用给定数量的2的表达式的唯一值

时间:2014-03-20 02:46:01

标签: algorithm combinations dynamic-programming

给定2的数量,通过构建最多给定数量的2的表达式,可以形成多少个唯一值,包括加法或乘法。

例如,如果n = 2,我们可以形成2个不同的值:

2 + 2 = 4
2 * 2 = 4
2     = 2

对于n = 3,我们可以形成4个不同的值(2,4,6和8):

2 * 2 * 2 = 8
2 * 2 + 2 = 6
2 + 2 * 2 = 6
2 + 2 + 2 = 6
2 * 2     = 4
2 + 2     = 4
2         = 2

我想知道任何n,不同可能值的数量。

我尝试了所有可能的组合并将它们添加到哈希映射中,但随着n的增加,comibnations呈指数级增长,因此蛮力不会起作用。我需要另一种计算方法或广义数学公式。

可以使用动态编程解决,因为我看到许多子问题被重复使用。

2 个答案:

答案 0 :(得分:5)

到目前为止,其他答案假设我们要计算不同的表达式的数量。这个答案假定我们正在寻找这些表达式可以评估的不同的数量。

我们假设您的表达大小最多为 n 。然后我们可以将其重写为 2 e [1] + 2 e [2] + ... + 2 e [m] e [i]> = 1 e [1] + e [2] + ... + e [m]< = n

假设 e [1]< = e [2]< = ...< = e [m] 。如果某些 i e [i] = e [i + 1] ,那么我们可以用单个指数 e [i] +替换两个相等的指数1 ,因为 2 e [i] + 2 e [i + 1] = 2 * 2 e [i] = 2 e [i] + 1 。由于 e [i] + 1< = e [i] + e [i + 1] ,新序列产生相同的值,并且仍然满足所有指数之和为小于或等于 n

所以我们只需要计算不同指数序列的数量 0< e [1]< e [2]< ......< E [M] 。很明显,每个代表一个不同的值,因为数字的二进制表示是唯一的(并且不同的指数恰好代表二进制表示)。

我们可以使用动态编程来计算这些序列,例如从最高到最低选择指数。

让我们将 f(n,hi)定义为选择不同指数的不同方式的数量,总和不超过 n ,其中最高指数是< = hi 。在每一步,我们都可以在 1 min(hi,n)之间任意选择下一个最高指数,或者停止选择指数。所以我们有了复发

f(0, hi) = 1  for all hi >= 0
f(n, hi) = 1 + sum(e = 1 to min(hi, n), f(n - e, e - 1))

这导致了一个简单的动态程序来解决问题。答案是f(n,n) - 1。我们需要减去一个,因为我们还计算了不选择任何指数的可能性,这导致总和0。但问题陈述不允许这样做。

以下是一些结果:

f(1,1) - 1 = 1
f(2,2) - 1 = 2
f(3,3) - 1 = 4
f(4,4) - 1 = 6
f(5,5) - 1 = 9
f(6,6) - 1 = 13
f(7,7) - 1 = 18
f(8,8) - 1 = 24
f(9,9) - 1 = 32
f(10,10) - 1 = 42
f(11,11) - 1 = 54
f(12,12) - 1 = 69
f(13,13) - 1 = 87
f(14,14) - 1 = 109

答案 1 :(得分:1)

如果没有涉及括号,则:

不是编程问题,而是组合问题。操作数是固定的,您只需选择N-1运算符从2(+*池中放置它们。有2^(N-1)个方法可以选择操作数。

N=2: 2^(2-1) = 2^1 = 2 (+, *)
N=3: 2^(3-1) = 2^2 = 4 (++, +*, *+, **)

无需编程,只需数学。

编辑:正如Niklas B.所指出的,你自己的例子与你提出的标准不符。上面的公式是“完全N两个”。如果你正在寻找“最多N两个”,被解释为“介于1和N两个之间”(因为我不确定如果你有0个结果会是什么结果),那么它是2^N-1

N=2: 2^2-1 = 4-1 = 3 (+, *, none)
N=3: 2^3-1 = 8-2 = 7 (++, +*, *+, **, +, *, none)

进一步编辑:如果您正在计算,那么您确实需要一些编程。最简单的解决方案是使用带有值的哈希映射,并在通过组合强制计算频率。在这种情况下,动态编程会比它的价值更麻烦,因为复杂度是O(N ^ 2),并且您可能不是在尝试计算百万操作数公式,而具有运算符优先级的位将使得不是非常直观的算法。