有人可以为以下问题提出最佳解决方案吗? 给定一个正负整数数组,返回最大“特殊和”。给定一个数组A,每个数组索引处的“特殊和”定义如下。
S[i] = S[i] + (S[i+1] + S[i+2]) + (S[i+3] + S[i+4] + S[i+5]) + (S[i+6] + S[i+7] + S[i+8] + S[i+9]) + .....
即对于索引为i的元素,我们添加下一个2个元素,然后添加下一个3个元素,然后添加下一个4个元素,直到数组中有可用的数字子集为止。
例如;数组A [1 3 1 2 5 -5] =>结果:8 说明:
S[0] = 1+(3+1)+(2+5-5)=7;
s[1] = 3+(1+2)=6;
S[3] = 1+(2+5)=8;
S[4] = 2+(5-5)=2;
S[5] = 5; S[6] = -5;
由于S [3]为最大值,因此是结果。 可以使用3loops解决,有没有最佳的解决方法?
答案 0 :(得分:1)
第1部分
给出长度为S
的数组N
时,请考虑以下顺序:
R[i] = S[i+1] + s[i+2] + s[i+3] + ... + s[N-1] + s[N]
R[i+1] = S[i+2] + s[i+3] + ... + s[N-1] + S[N]
...
R[N-1] = S[n]
这意味着R [k] = S [k] + R [k + 1]
循环nr 1:
from N to 0 do:
R[k] = s[k]
if R[k+1] exists do
R[k] = R[k] + R[k+1]
例如,如果N = 9的总和由下图中的x表示:
123456789
S[0] xxxxxxxxx
S[1] xxxxxxxx
S[2] xxxxxxx
S[3] xxxxxx
S[4] xxxxx
S[5] xxxx
S[6] xxx
S[7] xx
S[8] x
第2部分
我们假设每行求和的元素数必须为三角形(序列1 + 2 + 3 ...的元素,有效元素为1,3,6,10,...)
要形象化这一点,让我们举个例子:
123456789
S[0] xxxxxx
S[1] xxxxxx
S[2] xxxxxx
S[3] xxxxxx
S[4] xxx
S[5] xxx
S[6] xxx
S[7] x
S[8] x
请注意,每行(索引为i
)的末尾可能都存在间隙。当数字N-i不是三角形时,就会出现间隙。
例如,在索引i=0
:N-i = 9
处,小于9的最大三角数为6
要获取适合某个数字的最低三角数,请使用FLOOR以下公式:
function closest_triangle(n)
((sqrt(8*n+1) -1) / 2).floor
end
第2部分 现在,只需遍历i = 0 ... N的每个R [i]并减去不需要的部分:
for i in 0..N
for j in 0..closest_triangle(N-i)
R[i] = R[i] - S[i + j + 1]
end
end
当然,您可以存储部分相减和,因为它们会重复。例如,如果N = 21:
xxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxx
xxxxxxxxxxxxxxx
xxxxxxxxxxxxxxx
xxxxxxxxxxxxxxx
xxxxxxxxxxxxxxx
xxxxxxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxx
xxxxxx
xxxxxx
xxxxxx
xxx
xxx
xxx
x
x
因此,这将简化计算(存储最后一些数字的总和)。
现在开始复杂性
在第1部分中,我们创建大小为N的数组,并进行N个基本操作。
在第2部分中,如果将使用记忆(存储最后N个元素的总和)-那么我们还将有N个基本操作
因此算法将实现O(n)复杂度