问题 计算形式1 / r的k个分数的算法总计为1


特定 k,我们需要写 1 作为一个总和 k 形式的分数 1/r

例如,

  1. 对于 k=21 可以独特地写成 1/2 + 1/2
  2. 对于 k=31 可写成 1/3 + 1/3 + 1/3 要么 1/2 + 1/4 + 1/4 要么 1/6 + 1/3 + 1/2

现在,我们需要考虑所有这样的一组 k 总计达到的分数 1 并在所有这些集合中返回最高分母;例如,样本案例2,我们的算法应该返回 6

我在编码竞赛中遇到了这个问题,并且无法提出相同的算法。之后的一些谷歌搜索显示,这些分数被称为 埃及部分 但可能它们是一组不同的分数,总结到一个特定的值(不是 1/2 + 1/2)。此外,当他们的号码受到限制时,我找不到算法计算埃及分数(如果它们对这个问题都有帮助) k


6088
2017-08-06 18:09


起源

埃及分数的贪婪算法 - Jim Mischel
@JimMischel这是一篇很好的文章,但它似乎没有回答这个问题。 - RBarryYoung
@JimMischel我确实遇到过这种方法,但正如我在问题中所提到的,埃及分数是 不同 分数。此外,提出的贪婪算法没有考虑到我想要的确切 k 这样的分数。 - Shobhit
这里有一篇非常好的文章。 maths.surrey.ac.uk/hosted-sites/R.Knott/Fractions/egyptian.html - JNL


答案:


如果您想要做的就是找到最大的分母,那么没有理由找到所有可能性。你可以非常简单地做到这一点:

public long largestDenominator(int k){
    long denominator = 1;
    for(int i=1;i<k;i++){
        denominator *= denominator + 1;
    } 
    return denominator;
}

对于递归类型:

public long largestDenominator(int k){
    if(k == 1)
        return 1;
    long last = largestDenominator(k-1);
    return last * (last + 1); // or (last * last) + last)
}

为什么这么简单?

要创建集合,您需要插入将其保留的最大部分 1 在每一步(除了最后一步)。 “最大分数”,我的意思是价值,意味着最小的分母。

对于简单的情况 k=3,这意味着你开始 1/2。你不能适应另一半,所以你去 1/3。然后 1/6 遗留下来,给你三个学期。

对于下一个案例 k=4你接受了 1/6 最后,因为它不适合  一,我们需要另一个学期的空间。替换为 1/7因为那是最合适的价值。剩下的就是 1/42

根据需要重复。


例如:

  • 2 :[2,2]
  • 3 :[2,3,6]
  • 4 :[2,3,7,42]
  •  :[2,3,7,43,1806]
  • 6 :[2,3,7,43,1807,3263442]

如您所见,它迅速变得非常大。很快你就会溢出来 long 如果 k>7。如果您需要这样做,您需要找到一个合适的容器(即Java / C#中的BigInteger)。

它完美映射到 这个序列

a(n) = a(n-1)^2 + a(n-1), a(0)=1

你也可以看到与之的关系 西尔维斯特的序列

a(n+1) = a(n)^2 - a(n) + 1, a(0) = 2

维基百科 有一篇非常好的文章解释了两者之间的关系,正如彼得在评论中指出的那样。


16
2017-08-06 18:33



+1:而且 西尔维斯特的序列 证明这个答案必须是最优的(或者你会发现一个更接近1的答案) - Peter de Rivaz
@PeterdeRivaz它在维基百科上!我下次应该做一些研究,而不是用笔/纸来证明自己。< - Geobits
谢谢你这么简单的解决方案。我正在诅咒问题定居者在1小时的比赛中包括一个显然很难的问题。我还有很长的路要走。无论如何,再次感谢:) - Shobhit


我之前从未听说过埃及分数,但这里有一些想法:

理念

你可以用几何学思考它们:

  • 以单位正方形(1x1)开头
  • 绘制垂直或水平线,将正方形划分为相等的部分。
  • 可选地重复绘制任何子框内的线条均匀。
  • 随时停止。

存在的矩形将形成一组1 / n形式的分数,加到1。

你可以计算它们,它们可能等于你的'k'。

根据您将矩形划分为多少相等的部分,它将告诉您是否有1/2或1/3等等。 1/6是1/3的1/2或1/2的1/3。 (即你潜水2,然后其中一个子方框乘以3或反过来。)

想法2

你从1盒开始。这是1/1,k = 1。

当你细分n时,你将n加到方框的数量(k或分数总和)并减去1。

当您对这些框中的任何一个进行细分时,再次减去1并添加n,即分割数。请注意,n-1是您划分它们的行数。

更多

你将开始用k搜索答案。显然k * 1 / k = 1所以你有一个解决方案。

k-1怎么样?

那里有一个解决方案:(k-2)* 1 /(k-1)+ 2 *(1 /((k-1)* 2))

我是怎么做到的?我做了k-1个相等的部分(用k-2垂直线),然后将最后一个水平分成两半。

每个解决方案将包括:

  • 采取先前的解决方案
  • 使用j个较少的线和一些阶段并将其中一个框或子框分成j + 1个相等的部分。

我不知道是否可以通过从k * 1 / k开始重复这个规则来形成所有解

我知道你可以通过这种方式得到有效的重复。例如:k * 1 / k,j = 1 =>(k-2)* 1 /(k-1)+ 2 *(1 /((k-1)* 2))[从上面]但是k * 1 / k,j =(k-2)=> 2 *(1 /((k-1)* 2))+(k-2)* 1 /(k-1)[只是颠倒了顺序部分]

有趣

k = 7可以用1/2 + 1/4 + 1/8 + ... + 1 /(2 ^ 6)+ 1 /(2 ^ 6)表示,一般情况是1/2 + ...... + 1 /(2 ^(k-1))+ 1 /(2 ^(k-1))。

类似地,对于任何奇数k,它可以由1/3 + ... + 3 * [1 /(3 ^((k-1)/ 2)]表示。

我怀疑所有整数都有类似的模式,直到k。


0
2017-08-06 18:22