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

标签 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,不同可能值的数量。

我尝试了所有可能的组合并将它们添加到 HashMap 中,但是随着 n 的增加,组合呈指数级增长,因此蛮力无法奏效。我需要另一种计算方法或通用数学公式。

能不能用动态规划来解决,因为我看到很多子问题都是重复使用的。

最佳答案

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

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

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

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

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

让我们将 f(n,hi) 定义为选择总和不超过 n 且最高指数为 < em><= 嗨。在每一步,我们都可以在 1min(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

关于algorithm - 使用给定数量的 2 的表达式的唯一值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22522442/

相关文章:

java - 如何使用深度优先搜索列出电话簿中的号码?

c - 最小总和的最优选择

python - 如何枚举单词的组合?

python - 获取list python的所有有序组合

c++ - int/float/string值之间的操作,组合太多

c++ - 查找禁止字符串程序

scala - Scala 中的并行递归记忆化

algorithm - 仅使用两种硬币 (x,y) 支付账单金额 B 的最低小费

c# - 声学音频比较库

algorithm - 时间复杂度分析不一致