Algorithm 计算形式为1/r的k个分数加总为1的算法
给定Algorithm 计算形式为1/r的k个分数加总为1的算法,algorithm,Algorithm,给定k,我们需要将1写成k形式1/r分数的总和 比如说, 对于k=2,1可以唯一地写为1/2+1/2 对于k=3,1可以写成1/3+1/3或1/2+1/4+1/4或1/6+1/3+1/2 现在,我们需要考虑所有的 k<代码>分数,这些分数与 1 < /代码>相加,并在所有这些集合中返回最高分母;例如,在示例案例2中,我们的算法应该返回6 我在一次编码竞赛中遇到了这个问题,但我无法想出同样的算法。后来谷歌搜索发现,这些分数被称为埃及分数,但它们可能是一组不同的分数,加起来就是一个特定的值(不像1/
k
,我们需要将1
写成k
形式1/r
分数的总和
比如说,
k=2
,1
可以唯一地写为1/2+1/2
k=3
,1
可以写成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
的限制时,我找不到计算埃及分数的算法(如果它们对这个问题有帮助的话)。我以前从未听说过埃及分数,但这里有一些想法:
创意
你可以从几何角度来考虑它们:
- 从单位正方形(1x1)开始
- 画垂直线或水平线,将正方形分成相等的部分
- (可选)在任意子框内均匀重复绘制线
- 你想什么时候停就什么时候停
- 采取事先解决办法
- 使用无j线和一些阶段,并将其中一个方框或子方框划分为j+1等分
我怀疑在k之前的所有整数都有类似的模式。如果你只想找到最大的分母,没有理由找到所有的可能性。你可以非常简单地做到这一点:
public long largestDenominator(int k){
long denominator = 1;
for(int i=1;i<k;i++){
denominator *= denominator + 1;
}
return denominator;
}
为什么这么简单? 要创建集合,您需要在每个步骤(最后一步除外)插入将其保持在
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]
- 5:[2,3,7,431806]
- 6:[2,3,7,4318073263442]
k>7
,它将溢出long
。如果您需要这样做,您需要找到一个合适的容器(即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
有一篇很好的文章解释了两者之间的关系,正如Peter在评论中指出的。@JimMischel这篇文章很好,但似乎没有回答这个问题。@JimMischel我确实遇到过这种方法,但正如我在问题中提到的,埃及分数是不同的分数。另外,贪婪算法proPosite没有考虑到我想要的正是
k
这样的分数。这里有一篇非常好的文章。+1:证明了这个答案一定是最优的(否则你会发现更接近于1)@Peterderivez,它在维基百科上!我下次应该做一些研究,而不是在纸/笔上给自己证明。感谢这么简单的解决方案。我还在诅咒问题定居者在1小时的比赛中加入了一个显然很难的问题。我还有很长的路要走。无论如何,再次感谢:)
public long largestDenominator(int k){
if(k == 1)
return 1;
long last = largestDenominator(k-1);
return last * (last + 1); // or (last * last) + last)
}