私の地元のACMの章では、会議に参加する人々にドア賞を贈ります。ただし、プログラミングパズルを解くと勝つ可能性が高くなります(ただし、私は常にそのパズルを解きます)。したがって、一部の人には1つのエントリがあり、他の人には2つのエントリがあります。ラッフルプログラムの仕組みは、誰かがパズルを解くときに別のエントリを追加することではありません。代わりに、人が持っている「ライブ」の数を追跡し、その人がランダムサンプリングアルゴリズムの各パスで選択された場合、その人の数を減らします。したがって、次のように機能します。
Doorknob: 1. xnor: 2. Justin: 2. Alex: 1. Dennis: 2.
次に、プログラムはのいずれかをランダムに選択し[Doorknob, xnor, Justin, Alex, Dennis]
、数値をデクリメントします(たとえば、選択しますJustin
)。
Doorknob: 1. xnor: 2. Justin: 1. Alex: 1. Dennis: 2.
そして繰り返します。誰かの「ライブ」の数が0
(Justin
再度選択しよう)になった場合、リストから削除されます。
Doorknob: 1. xnor: 2. Alex: 1. Dennis: 2.
これは、一人が残るまで続きます。その人が勝者です。
さて、本当の問題は、私が勝つ可能性はどのくらいだったのかということです。
次の2つの入力が与えられます。
n
。これはチャレンジに参加した人の数ですk
。これは、n
2人の命を持っている(そのうちの)人の数です。この番号には常にあなたが含まれます。
だから、もし私が関数を持っていてp
を呼び出したp(10, 5)
場合、それは合計10人の人が賞金を獲得する確率になります。
勝つ確率を正確に、または小数として出力することが期待されています。いずれにしても、答えは4を含め、正確にアップしてある必要があります番目の小数点後の小数点以下の場所。その桁に丸めるかどうかはあなた次第です。
あなたのソリューションは、高い確率で小数第 4 位までの回答を出力するランダム化ソリューションかもしれません。使用するビルトインRNGは本当にランダムであり、少なくとも90%の確率で正しい答えを出力する必要があると仮定できます。
さらに、コードはのためにのみ動作する必要がありますがn, k <= 1000
、好奇心の強い人向けのテストケースよりも大きなテストケースを提供しました。
テストケース
注:これらのいくつかは一般式です。
n, k | output
----------+---------
1, 1 | 1
2, 2 | 0.5
2, 1 | 0.75
3, 1 | 11/18 = 0.611111111
1000, 1 | 0.007485470860550352
4, 3 | 0.3052662037037037
k, k | 1/k
n, 1 | (EulerGamma + PolyGamma[1 + n])/n (* Mathematica code *)
| (γ + ψ(1 + n))/n
10, 6 | 0.14424629234373537
300, 100 | 0.007871966408910648
500, 200 | 0.004218184180294532
1000, 500 | 0.0018008560286627948
---------------------------------- Extra (not needed to be a valid answer)
5000, 601 | 0.0009518052922680399
5000, 901 | 0.0007632938197806958
別のいくつかのチェックについてはp(n, 1) * n
、次のようにします。
n | output
------+---------
1 | 1
2 | 1.5
3 | 1.8333333333333335
10 | 2.928968253968254
100 | 5.1873775176396215
-------------------------- Extra (not needed to be a valid answer)
100000| 12.090146129863305
k
1つずれていると思います)