C++でN個のコンテナからXを引き当てる確率を最大化する方法
確率は一般に次の式で表されます。
Pi =(有利な結果の数)/(結果の総数)
ここで、コンテナの個数を表す整数 N が与えられ、2つの数値 X と Y のコピーがそれぞれ N 個ずつあるとします。この課題では、X のコピーを N 個のコンテナへ振り分けることで、「X を引き当てる確率」を最大にすることを目指します。
上記の定義から、Pi を最大化するには分子(有利な結果の数)を大きくするか、分母(結果の総数)を小さくすればよいことがわかります。最適な戦略は、Y のコピーを1つのコンテナに集中させ、それ以外のすべてのコンテナには X のみを入れることです。具体的には次のように配置します。
- N-1 個のコンテナには、それぞれ X のコピーを1個ずつ入れる
- 残り1個のコンテナには、X のコピー1個と Y のコピー N 個を入れる
最大確率の導出
最初の N-1 個のコンテナから X を引き当てる確率は次のとおりです。
P(n-1) = 1
最後のコンテナから X を引き当てる確率は、X 1個に対して Y が N 個存在するため、次のようになります。
Pn = 1 / (N + 1)
全体の確率 Pm は、各コンテナの確率を平均すると次の式にまとめられます。
Pm = ((N − 1) × 1 + 1 / (N + 1)) / N
∴ Pm = N / (N + 1)
入出力例
入力: N = 1
出力: N = 1 のときの最大確率は 0.5
説明: コンテナが1個だけで、その中に X と Y がそれぞれ1個ずつ入っているため、X を引き当てる最大確率は 0.5 となります。
入力: N = 3
出力: N = 3 のときの最大確率は 0.75
説明: すべてのコンテナに X のコピーが1個ずつ入っており、最後のコンテナには Y のコピー3個がすべて集められています。
プログラムのアプローチ
- コンテナの個数 N を整数値として受け取ります。
- X を引き当てる最大確率を格納する変数(例:maxP)を宣言します。
- 与えられた N に対して、maxP = N / (N + 1) として計算します。
C++による実装例
#include <bits/stdc++.h>
using namespace std;
int main(){
int N = 3;
double maxP = (double)N / (N + 1);
cout << "Maximum Probability for N = " << N << " is, " << maxP << endl;
return 0;
}
出力
上記のコードを実行すると、次の出力が得られます。
Maximum Probability for N = 3 is, 0.75
-
C++で配列内に存在するキーKの出現確率を求める方法
問題概要サイズ「n」の配列が与えられ、その配列内に指定された要素 k が存在する場合に、その出現確率を求めることが課題です。配列の要素数と等しい「n」まで配列全体を走査し、指定された要素(キー)「k」を検索します。要素が配列内に存在する場合はその確率を計算して返し、存在しない場合は 0 を出力します。入力arr[] = { 1, 2, 3, 4, 5, 6} K = 5出力配列におけるキー 5 の確率 : 0.166入力arr[] = { 1,2,3,4,5,6,7 } K = 8出力配列におけるキー 8 の確率 : 0考え方上記はサイズ 7 の配列とキー 2 を例とした説明です。この場合、配
-
C++で解くチェス盤上のナイトが盤内に残る確率の求め方
問題概要 N×Nのチェス盤があるとします。ナイトはr行c列目のマスからスタートし、ちょうどK回の移動を試みます。行と列は0始まりのインデックスで表されるため、左上のマスは(0, 0)、右下のマスは(N-1, N-1)となります。 ナイトは1つのマスから8種類の異なるマスへ移動することができます。その移動パターンは下図の通りです。 ナイトは移動のたびに、8つの可能な移動の中からランダムに1つを選択します。そして、ちょうどK回の移動を完了するか、チェス盤の外に出てしまうまで移動を続けます。この問題では、ナイトが移動を終えた時点で盤上に残っている確率を求めます。 例えば、入力が「3, 2, 0,