◆岩手県 高梨 さんからの解答。
配当に関する条件を読みかえて、
4回目に「ビンゴ」が成立しているときは,賭けたコインの200倍
5回目に「ビンゴ」が成立しているときは,賭けたコインの100倍
6回目に「ビンゴ」が成立しているときは,賭けたコインの50倍
7回目に「ビンゴ」が成立しているときは,賭けたコインの25倍
8回目に「ビンゴ」が成立しているときは,賭けたコインの15倍
9回目に「ビンゴ」が成立しているときは,賭けたコインの5倍
10回目に「ビンゴ」が成立しているときは,賭けたコインの5倍
のコインが手元に戻ってくる(毎回重複計算)、としても配当は同じになります。
また、各N回目で「ビンゴ」が成立している確率を独立事象だとしても配当の期待値は変わりません。
・4回目
数字4つの組み合わせ:24C4=10626
ビンゴになる組み合わせ:4
(中央を通る縦横斜めのみ)
・5回目
数字5つの組み合わせ:24C5=42504
ビンゴになる組み合わせ:8+4*20=88
(中央を通らないライン+通るライン)
・6回目
数字6つの組み合わせ:24C6=134596
ビンゴになる組み合わせ:8*20+4*20C2=920
(同上)
・7回目
数字7つの組み合わせ:24C7=346104
ビンゴになる組み合わせ:8*20C2+4*20C3=6080
(同上)
・8回目
数字8つの組み合わせ:24C8=735471
ビンゴになる組み合わせ:
8*20C3+4*20C4-4C2=28494
(同上-重複しているダブルビンゴ)
重複は中央を通る縦横斜めの二本の組み合わせ(4C2)のみ
・9回目
数字9つの組み合わせ:24C9=1307504
ビンゴになる組み合わせ:
8*20C4+4*20C5-488=100288
(同上)
重複は、
中央を通る縦横斜めの二本の組み合わせ(4C2*16)
中央通りとそれ以外の組で平行なもの(8)
中央通りとそれ以外の組で交わるもの(8*3*16)
の合計(488)
・10回目
数字10の組み合わせ:24C10=1961256
ビンゴになる組み合わせ:
8*20C5+4*20C6-3728=275344
(同上)
重複は、
中央を通る縦横斜めの二本の組み合わせ(4C2*16C2)
中央通りとそれ以外の組で平行なもの(8*16)
中央通りとそれ以外の組で交わるもの(8*3*16C2)
の合計(3728)
以上よりコインを300枚賭けた時の配当の期待値は、
300* (200* | 4 10626 | +100* | 88 42504 | +50* | 920 134596 | +25* | 6080 346104 | +15* | 28494 735471 | +5* | 100288 1307504 | +5* | 275344 1961256 | ) |
【感想】
条件を読みかえて、案外すんなりいくかな?と思ったのですが……。
結局ほとんど力押しで解いてしまいました。
計算ミスが無いか非常に心配です(’’;。
◆北海道 小西 儀紀 さんからの解答。
【解答】
期待倍率 = | 4424360 1716099 | = 2.5781…倍 |
300枚賭けた場合の期待枚数 = | 442436000 572033 | = 773.44…枚 |
【詳細】
2列以上ビンゴしても無意味なので、1列ビンゴした段階で次の玉は取り出さずに終了することとする。
24個の玉からn個の玉を取り出すとき、
n-1個目まででビンゴせずにn個目の玉でビンゴする順列の総数をAn、
n個目の玉でもビンゴしない順列の総数をBnとする。
また、n-1個目まででビンゴせずにn個目の玉を引いた時の順列の総数をCnとする。
つまり、Cn = An + Bnである。
玉を引いていないn = 0のとき、A0 = 0、B0 = 1、C0 = 1と定義する。
Cnはn-1個目でビンゴしていない順列に対してn個目を引いた順列の総数でもあり、
n個目の玉の選択肢は25-n通りなので、
Cn = Bn-1 * (25-n) と表せる。
従って、Anを求めればBnとCnも決定する。
中心(25)は初めから塗られているので、Anを、
ビンゴ列に中心が使われている順列の総数A1nと、
ビンゴ列に中心が使われていない順列の総数A2nに分けて考える。
(An = A1n + A2n)
y <0のときxCy = 0とすると、1 ≦ n ≦ 10の範囲で、
A1n | = | 2 * (n-1)! * 4 * (20Cn-4-6 * 16Cn-8-4 * 15Cn-9) + 2 * (n-1)! * 4 * (20Cn-4-9 * 16Cn-8) |
= | 2 * (n-1)! * 4 * (2 * 20Cn-4-15 * 16Cn-8-4 * 15Cn-9) | |
A2n | = | 8 * (n-1)! * (5 * 19Cn-5-5 * 3 * 16Cn-8-4 * 4 * 15Cn-9-1 * 5 * 15Cn-9-5 * 3 * 14Cn-10)-16 * (n-1)! * 15Cn-9 |
= | 8 * (n-1)! * (5 * 19Cn-5-15 * 16Cn-8-23 * 15Cn-9-15 * 14Cn-10) |
考え方は、
赤字部分は最終的にビンゴする列の数(中央を含む縦横2通り、斜め2通り、中央を含まない縦横8通り)、
青字部分はビンゴ列以外の組み合わせ(引き算部分はn個目を引く前に赤字のビンゴ列以外がビンゴしてしまう配置を除いている)、
緑字部分はn個のマス(ビンゴ列とそれ以外)を塗る順列のうち、最後にビンゴ列が塗られる順列の総数、
ピンク字部分は前半で縦と横が同時にビンゴする順列を重複して数えているので、その補正。
この式からA1n、A2n、An、Bn、Cn、
n個目が引ける確率Dn = | Dn-1 * Bn-1 Cn-1 | (D0 = 1と定義する)、 |
n個目が引けてビンゴする確率En = | Dn * An Cn | 、 |
n | A1n | A2n | An | Bn | Cn | Dn | En | 倍率 | En * 倍率 |
0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | - | - |
1 | 0 | 0 | 0 | 24 | 24 | 1 | 0 | - | - |
2 | 0 | 0 | 0 | 552 | 552 | 1 | 0 | - | - |
3 | 0 | 0 | 0 | 12144 | 12144 | 1 | 0 | - | - |
4 | 96 | 0 | 96 | 254928 | 255024 | 1 | 0.000376435 | 400 | 0.150574064 |
5 | 7680 | 960 | 8640 | 5089920 | 5098560 | 0.999623565 | 0.001693958 | 200 | 0.338791643 |
6 | 364800 | 91200 | 456000 | 96252480 | 96708480 | 0.997929607 | 0.004705439 | 100 | 0.470543949 |
7 | 13132800 | 4924800 | 18057600 | 1714487040 | 1732544640 | 0.993224167 | 0.010351967 | 50 | 0.517598344 |
8 | 390096000 | 194745600 | 584841600 | 28561438080 | 29146279680 | 0.9828722 | 0.019722056 | 25 | 0.493051392 |
9 | 9923235840 | 6166379520 | 16089615360 | 440893393920 | 456983009280 | 0.963150145 | 0.033910922 | 10 | 0.339109224 |
10 | 219644006400 | 162512179200 | 382156185600 | 6231244723200 | 6613400908800 | 0.929239222 | 0.053696203 | 5 | 0.268481014 |
期待倍率 | 2.578149629 | ||||||||
期待枚数 | 773.4448887 |
4424360 1716099 | 、 | 442436000 572033 | となる。 |
【備考】
ドラゴンクエストVIIIのカジノですね(^^
自分でも気になっていて、8個までは計算していました。
9個と10個を考慮した式に修正してみたのですが、青字部分の引き算で抜けがないか心配です…
簡単なプログラムで全順列を数えて、n = 9 までは正しいことを確認してあります。
(n = 10 は計算中)
さらに個数を増やした場合も、ビンゴ列以外でビンゴしないように青字の組み合わせを
うまく引き算していけばよいのですが、面倒なので考えていません…(^^;
◆三重県 とくしん さんからの解答。
C言語でプログラムを書いて求めました。
プログラムは224個全ての穴の開け方に対してビンゴしているかどうかを調べるという極めて異常な方法で計算しています。
ビット演算を多用しているのでソースコードは読み辛いと思いますがその分高速に動作します。
出力結果 穴の数 ビンゴしている確率 丁度ビンゴする確率 配当金の期待値 3 0.000000 0.000000 0.000000 4 0.000376 0.000376 45.172219 5 0.002070 0.001694 101.637493 6 0.006776 0.004705 141.163185 7 0.017128 0.010352 155.279503 8 0.036850 0.019722 147.915417 9 0.070761 0.033911 101.732767 10 0.124457 0.053696 80.544304 11 0.203392 0.078935 0.000000 12 0.311040 0.107648 0.000000 13 0.446032 0.134992 0.000000 14 0.598912 0.152880 0.000000 15 0.750609 0.151697 0.000000 16 0.876234 0.125626 0.000000 17 0.956522 0.080287 0.000000 18 0.991322 0.034800 0.000000 19 0.999435 0.008113 0.000000 20 1.000000 0.000565 0.000000 21 1.000000 0.000000 0.000000期待倍率 = 2.578150
以下プログラム
#include <stdio.h> #define BET 300 // 何枚賭けるか /* ボードの座標をビットで表す。 ボードとビットの対応は次のようにする 000001 000002 000004 000008 000010 000020 000040 000080 000100 000200 000400 000800 001000 002000 004000 008000 010000 020000 040000 080000 100000 200000 400000 800000 */ // ビンゴするラインの定義。 const int c_nLine[12] = { // 横 0x00001F, 0x0003E0, 0x003C00, 0x07C000, 0xF80000, // 縦 0x084421, 0x108842, 0x210084, 0x421108, 0x842210, // 斜め 0x820041, 0x088110, }; // 配当金 const int c_nPay[25] = { 0,0,0,0, 400, 200, 100, 50, 25, 10, 5, 0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; // 立っているビットの数を数える inline int CountBits(int num) { int i, s = 0; for(i = 1 ; i < 0x01000000 ; i <<= 1) // 高速化の為下位24ビットのみ調べる { // 本当はテーブル化を併用した方が速いのだが。 s += i & num ? 1 : 0; } return s; } void main(void) { int anCount[25]; // [n]箇所空いている場合の数 int anTrueBingo[25]; // [n]箇所空いた盤面がビンゴしている確率(母数はanCount) int anJustBingo[25]; // [n]箇所目で丁度ビンゴする確率(母数はanCountのn倍) int i, j, n, b; double pay; for(i = 0 ; i < 25 ; i++) { anCount[i] = 0; anTrueBingo[i] = 0; anJustBingo[i] = 0; } for(i = 0 ; i < 0x01000000 ; i++) // 1677万通りだからこそ出来る荒業 { // iはループカウンタ兼盤面のデータそのもの。 n = CountBits(i); // 空いている穴の数で分類 anCount[n]++; b = -1; // ビンゴ列の判定用に全ビットを立てる。下位24ビットでも可 for(j = 0 ; j < 12 ; j++) { if(!((i ^ c_nLine[j]) & c_nLine[j])) // ある列でビンゴしているか判定 { b &= c_nLine[j];// ビンゴしていた場合その列に含まれないビットを落とす } // 全てのビンゴしている列の交点となるビットのみが残る } if(b != -1) // 1列でもビンゴしていた場合 { anTrueBingo[n]++; anJustBingo[n] += CountBits(b); // ビンゴしている列の交点の数だけ加算 } // 交点=そこを抜くと全てのビンゴ列が消える点 } pay = 0; printf("穴の数 ビンゴしている確率 丁度ビンゴする確率 配当金の期待値\n"); for(i = 3 ; i < 22 ; i++) { pay += (double)anJustBingo[i] / anCount[i] / i * c_nPay[i]; printf(" %2d %8.6f %8.6f %10.6f\n", i, (double)anTrueBingo[i] / anCount[i], (double)anJustBingo[i] / anCount[i] / i, (double)anJustBingo[i] / anCount[i] / i * c_nPay[i] * BET ); } printf("期待倍率 = %8f\n", pay); printf("%d枚賭けた時の配当金の期待値 = %8f\n", BET, pay * BET); rewind(stdin);getchar(); }