问题陈述:
我们得到了
一组T号S1,S2,...... ST
一个名为Range
这意味着S1可以采用(2 * Range + 1)值(S1-Range,S1-Range + 1,... S1,S1 + 1,...... S1 + Range) 类似地,S2,... ST可以采用2 * Range + 1值
问题1:如何枚举所有可能的序列?即所有(2 * Range-1)^ T序列(S1-Range,S2,... ST),S1-Range + 1,S2,... ST),.....,(S1,S2) -Range,S3,...... ST)等
问题2:我如何仅列出总和为S1 + S2 + ... + ST?
的序列问题1:我正在考虑的方法是做一个
for (i=0; i<pow(Range,T);i++)
{
Sequences that can be derived from i are
1. {Si + i mod pow(Range,i)}
2. {Si - i mod pow(Range,i)}
}
还有其他更优雅的解决方案吗?
此外,对问题2的任何想法?
答案 0 :(得分:2)
对于#1,一种方法是将其视为增加数字的方式。你递增最后一个数字,当它溢出时你将它设置回初始值(0)并递增下一个数字。
因此,创建一个大小为T的数组,然后将元素初始化为(S1-Range,S2-Range,...,ST-Range)。打印出来。
现在将最后一个值增加到ST-Range + 1。打印出来。继续递增和打印,直到达到ST +范围。尝试增加时,重置回ST-Range,然后向左移动一个位置并递增。如果溢出也重复。如果一直向前移动,你就完成了,否则打印出来。
// Input: T, S[T], Range
create V[T]
for (i in 1..T):
V[i] = S[i] - Range
loop forever {
print V
i = T
V[i]++
while V[i] > S[i] + Range {
V[i] = S[i] - Range
i--
if i < 1:
return // we're done
V[i]++
}
}
对于#2,它有点不同。对于描述,我将忽略S的值,并为每个位置忽略delta(-Range,...,0,...,+ Range)的焦点,称之为D.
由于sum(D)= 0,初始值集为(-Range,-Range,...,+ Range,+ Range)。如果T是偶数,则前半部分是-Range,后半部分是+ Range。如果T为奇数,则中间值为0.
现在看看你希望如何进行迭代:
-2 -2 0 2 2
-2 -2 1 1 2
-2 -2 1 2 1
-2 -2 2 0 2 (A)
-2 -2 2 1 1
-2 -2 2 2 0
-2 -1 -1 2 2
-2 -1 0 1 2
-2 -1 0 2 1
-2 -1 1 0 2
这里的逻辑是你跳过最后一位数,因为它总是其他数字的函数。您可以递增可以递增的最右侧数字,并将其右侧的数字重置为可能得到总和(D)= 0的较低值。
逻辑有点复杂,所以我会让你有趣的写作。 ; - )
一个好的帮助方法,如果给定一个起始增量,将是一个将某个位置后的数字重置为最低可能值的方法。然后,您可以通过调用reset(1, 0)
来使用它来初始化数组,即使用起始增量0重置位置1..T。
然后,当您在上面标记为A的步骤中将D [3]增加到2时,您调用reset(4, -2)
,即使用-2的起始delta重置位置4..5。最后一位的最大值为2(范围),则表示D [4]不能低于0.