假设您有20面骰子。您开始滚动该骰子,并且必须滚动数十次才能最终滚动所有20个值。您想知道,我有多少卷才能有50%的机会看到全部20个值?n
在滚动所有n
面之前,我需要滚动几卷双面模具?
经过研究,您发现存在一个公式,用于计算滚动后所有值滚动的机会。n
r
P(r, n) = n! * S(r, n) / n**r
其中S(a, b)
表示第二种斯特林数,是将一组n个对象(每个滚动)划分为k个非空子集(每侧)的方式的数量。
您还可以找到OEIS序列,我们称之为R(n)
,对应于最小的r
,其中P(r, n)
至少50%。面临的挑战是n
尽可能快地计算此序列的th项。
挑战
- 给定一个
n
,找到最小的r
,其中P(r, n)
大于或等于0.5
或50%。 - 从理论上讲,您的代码应将任何非负整数
n
作为输入,但是我们将仅在范围内测试您的代码1 <= n <= 1000000
。 - 对于进球,我们将采取运行所需的总时间
R(n)
上的投入1
过10000
。 - 我们将通过
R(n)
在输出中运行我们的版本来检查您的解决方案是否正确,以查看是否P(your_output, n) >= 0.5
和P(your_output - 1, n) < 0.5
,即您的输出实际上r
是给定输出的最小值n
。 - 您可以
S(a, b)
在解决方案中使用任何定义。Wikipedia有几个定义可能会对您有所帮助。 - 您可以在解决方案中使用内置函数,包括那些可以计算
S(a, b)
甚至P(r, n)
直接计算的函数。 R(n)
尽管这两个都不是硬性限制,但您最多可以对1000个值和一百万个斯特林数进行硬编码,并且如果可以说服您提高或降低它们,则可以更改。- 你并不需要检查每一个可能的
r
之间n
和r
我们要找的,但你需要找到最小的r
,不是任何r
地方P(r, n) >= 0.5
。 - 您的程序必须使用Windows 10上可自由运行的语言。
用于测试您的解决方案的计算机的规格为i7 4790k, 8 GB RAM
。感谢@DJMcMayhem提供了用于测试的计算机。可以随意添加您自己的非官方时间,以供参考,但DJ可以对其进行测试之后,将提供官方时间。
测试用例
n R(n)
1 1
2 2
3 5
4 7
5 10
6 13
20 67 # our 20-sided die
52 225 # how many cards from a huge uniformly random pile until we get a full deck
100 497
366 2294 # number of people for to get 366 distinct birthdays
1000 7274
2000 15934
5000 44418
10000 95768
100000 1187943
1000000 14182022
如果您有任何疑问或建议,请告诉我。祝你好运,优化!