如何确定长度为N的数组的数量,使其满足以下两个条件:
示例:让 N = 2
然后将XOR总和为零= 6的总数组
是- (0,0) (1,1) (2,2) (3、3) (4、4) (5,5)
那么如何有效地找出这一点呢?
答案 0 :(得分:4)
可以使用dynamic programming在 O(N)中完成。
假设dp[i][j]
是许多数组,这样它们就有i
个元素,它们的XOR和为j
。
请注意0 <= j <= 7
,因为如果N == 6
数组[1, 2, 4, 4, 2, 1]
匹配,但是其前缀[1, 2, 4]
具有XOR-sum7。同样,您将无法获得更多XOR-sum。比7大,因为分解为2的幂时,0到5范围内的所有数字除2 ^ 2、2 ^ 1和2 ^ 0之外都不能有其他项。
以下是使用先前计算的值来计算dp[i][j]
的公式:
dp[i][j] = 0
# k is XOR-sum of previously calculated number of arrays of length i-1.
for k in range(0, 8):
# x is a number we append to arrays of length i-1 so XOR-sum is j.
x = j xor k
if x <= 5:
dp[i][j] += d[i - 1][k]
这就是其余的代码:
# Assume there's a two dimensional array of integers dp of size N+1 x 8.
# Dynamics initialization.
# There's only one possible array of length 0: []. It's XOR-sum is 0.
dp[0][0] = 1
for i in range(1, 8):
dp[0][i] = 0
# Dynamics state calculation.
for i in range(1, N+1):
for j in range(0, 8):
# Here comes code from above.
dp[i][j] = 0
for k in range(0, 8):
x = j xor k
if x <= 5:
dp[i][j] += d[i - 1][k]
# Answer is dp[N][0].
print(dp[N][0])
动态状态计算进行 N * 8 * 8 次迭代,因此复杂度为 O(N)(请注意,尽管存在线性复杂度,常数64可能会很大)。
有一种方法可以使用matrix binary exponentiation在 O(log N)中对其进行计算。简要地说:您需要计算一个8x8的矩阵M
告诉dp[i-1][*]
值如何变成dp[i][*]
值;然后计算dp[0] * M^N
,其中dp[0]
是[1, 0, 0, 0, 0, 0, 0, 0]
(与动态初始化完全一样)。