所以我为你得到了一些绊脚石。我需要编写一个函数,它接受一个数字(称为K)并输出n个数字,其中总和如果这些数字== K.
例如,如果我给出这个函数(100,3),它将输出[1,2,97],[1,3,96],[1,4,95] ... [97,1, 2]
我的功能是三位数:
k = 100
r = []
0.upto(k/2) do |a|
(a+1).upto(k/2) do |b|
c = k-(a+b)
r << [a,b,c]
end
end
我如何编写这个需要n位数的函数?
答案 0 :(得分:0)
这可能不是世界上最好的解决方案(需要的内存随O(k^3)
而增长),但它是一个解决方案。我欢迎提出改进建议。
您可能有兴趣阅读integer partitions,这是我们在此重复计算的内容。
您正在寻找一个功能f(k,n)
,它会计算将数字k
划分为n
部分的方式的数量。问题的部分原因是,在计算分区两次时很难分辨。
我将通过使用另一个函数g(k,n,s)
来解决此问题,该函数计算将数字k
划分为n
部分的方式的数量,其中允许的最大值是 s
。例如,我们不计算(90,8,2)
中的分区(64,20,16)
或g(100,3,60)
,因为它们使用的值大于s=60
。
g(k,n,s) = f(k,n)
时{p> s>=k
(即我们不会在分区中允许的值上放置最大值)。
关于g(k,n,s)
的一些事实:
k==n
隐含g=1
,因为将k
分区为k
部分的唯一方法是使用所有1
s(因此s
是因为我们使用尽可能少的数字而无关紧要)n>k
隐含g=0
,因为我们无法将k
分区为k
部分以上s==1
隐含g=1
如果k==n
和g=0
,则因为放置1
的最大值只允许k
的分区k
部分(全部)n==1
隐含g=1
如果s>=k
和g=0
,则k
到n=1
部分的唯一分区要求我们使用k
{1}}本身在分区s<RoundUp(k/n)
隐含g=0
,因为我们无法使用小于k
的值将n
分割为k/n
部分;例如,我们不能仅使用小于100
的值对4
个25
个分区进行分区。s>k-n+1
隐含g(k,n,s) = g(k,n,s-1)
,因为在s
添加任何新分区后增加最大值k-n+1
;例如,100
到3
部分的任何分区都不会包含大于100-3+1 = 98
的数字g(k,n,s) = g(k,n,s-1) + g(k-s,n-1,s)
。这只会使用值s
将所有分区添加到我们使用最大值s-1
现在我只选择最大数量K
并将所有这些事实抛出到嵌套的for
循环中,并推导出g(k,n,s)
的每个值。要获得f(k,n)
,我只需找到g(k,n,k)
。
这是算法,不适合大K
。
g = (K by K by K) array of all zeros
for k = 1:K
for n = 1:K
for s = 1:K
if (k==n)
val = 1;
else if (n>k)
val = 0;
else if s==1
val = int(k==n);
else if n==1
val = int(s>=k);
else if s<RoundUp(k/n)
val = 0;
else if s>(k-n+1)
val = g(k,n,s-1);
else
val = g(k,n,s-1) + g(k-s,n-1,s);
end
g(k,n,s) = val;
end
end
end
对于f(100,3) = g(100,3,100)
,我获得了833
个唯一分区,如果您使用强力方法,则可以看到这些分区是正确的。如果你看到任何错误,请指出错误。