/*
プログラミングのお題スレ Part15
//mevius.5ch.net/test/read.cgi/tech/1564310397/4
4 名前:デフォルトの名無しさん[sage] 投稿日:2019/07/28(日) 21:32:12.69 ID:MO+jaDzY
お題
とあるゲームでは、10面ダイスによってスコアを次のように定める
1. x個のダイスを全部振る
2. 振ったダイスのうち、最大の出目をスコアとする
3. 出目がc以上のダイスが存在するなら、その全てのダイスを使って同じ試行を行い、スコアに加算する
例えばc=7の時、2個のダイスの結果が(10,7)→(8,3)→(2)ならスコアは10+8+2=20となる
最初に振るダイスの個数Nとc(≧2)が分かっている時、スコアの期待値を求めよ
*/
class Ideone
{
public static void main
(String[] args
) {
for (int n = 1; n <= 10; n++)
odai(n, 5);
}
static void odai(int n, int c)
{
System.
out.
printf("N=%d, c=%d -> %f%n", n, c, calc
(10, n, c
)); }
/**
* @param faces ダイスの面数
* @param dice ダイスの数
* @param c この出目以上のダイスはもう一回振れる
* @return 期待値
*/
static double calc(int faces, int dice, int c)
{
double[] scores = new double[dice + 1];
double probability
= Math.
max(0,
1 - (c
- 1d
) / faces
);
// n個のダイスを振った時の期待値を求めてscores[n]に入れる
for (int n = 1; n <= dice; n++)
{
double score = expectedMaxValue(faces, n);
for (int reroll = 1; reroll < n; reroll++)
{
score += scores[reroll] * binomialDistribution(n, reroll, probability);
}
scores[n] = score / (1 - binomialDistribution(n, n, probability));
}
return scores[dice];
}
/**
* 指定回ダイスを振った時の出目の最大値の期待値を求める
* @param faces ダイスの面数
* @param num ダイスを振る数
* @return 出目の最大値の期待値
*/
static double expectedMaxValue(int faces, int num)
{
double value = 0;
for (int i = 1; i <= faces; i++)
{
value
+= (Math.
pow(i, num
) - Math.
pow(i
- 1, num
)) * i
; }
return value
/ Math.
pow(faces, num
); }
static long binomialCoefficients(int n, int k)
{
if (k == 0 || k == n) return 1;
if (k == 1 || k == n - 1) return n;
long[] array = new long[n + 1];
array[0] = 1;
for (int i = 1; i <= n; i++)
{
array[i] = 1;
for (int j = i - 1; j >= 1; j--)
{
array[j] += array[j - 1];
}
}
return array[k];
}
static double binomialDistribution(int n, int k, double p)
{
return binomialCoefficients
(n, k
) * Math.
pow(p, k
) * Math.
pow(1 - p, n
- k
); }
}
LyoK44OX44Ot44Kw44Op44Of44Oz44Kw44Gu44GK6aGM44K544OsIFBhcnQxNSAKLy9tZXZpdXMuNWNoLm5ldC90ZXN0L3JlYWQuY2dpL3RlY2gvMTU2NDMxMDM5Ny80Cgo0IOWQjeWJje+8muODh+ODleOCqeODq+ODiOOBruWQjeeEoeOBl+OBleOCk1tzYWdlXSDmipXnqL/ml6XvvJoyMDE5LzA3LzI4KOaXpSkgMjE6MzI6MTIuNjkgSUQ6TU8ramFEelkK44GK6aGMCuOBqOOBguOCi+OCsuODvOODoOOBp+OBr+OAgTEw6Z2i44OA44Kk44K544Gr44KI44Gj44Gm44K544Kz44Ki44KS5qyh44Gu44KI44GG44Gr5a6a44KB44KLCjEuIHjlgIvjga7jg4DjgqTjgrnjgpLlhajpg6jmjK/jgosKMi4g5oyv44Gj44Gf44OA44Kk44K544Gu44GG44Gh44CB5pyA5aSn44Gu5Ye655uu44KS44K544Kz44Ki44Go44GZ44KLCjMuIOWHuuebruOBjGPku6XkuIrjga7jg4DjgqTjgrnjgYzlrZjlnKjjgZnjgovjgarjgonjgIHjgZ3jga7lhajjgabjga7jg4DjgqTjgrnjgpLkvb/jgaPjgablkIzjgZjoqabooYzjgpLooYzjgYTjgIHjgrnjgrPjgqLjgavliqDnrpfjgZnjgosK5L6L44GI44GwYz0344Gu5pmC44CBMuWAi+OBruODgOOCpOOCueOBrue1kOaenOOBjCgxMCw3KeKGkig4LDMp4oaSKDIp44Gq44KJ44K544Kz44Ki44GvMTArOCsyPTIw44Go44Gq44KLCuacgOWIneOBq+aMr+OCi+ODgOOCpOOCueOBruWAi+aVsE7jgahjKOKJpzIp44GM5YiG44GL44Gj44Gm44GE44KL5pmC44CB44K544Kz44Ki44Gu5pyf5b6F5YCk44KS5rGC44KB44KICiovCmNsYXNzIElkZW9uZQp7CiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKQogICAgewogICAgICAgIGZvciAoaW50IG4gPSAxOyBuIDw9IDEwOyBuKyspCiAgICAgICAgICAgIG9kYWkobiwgNSk7CiAgICB9CiAgICAKICAgIHN0YXRpYyB2b2lkIG9kYWkoaW50IG4sIGludCBjKQogICAgewogICAgICAgIGlmIChjIDwgMikgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRmKCJOPSVkLCBjPSVkIC0+ICVmJW4iLCBuLCBjLCBjYWxjKDEwLCBuLCBjKSk7CiAgICB9CgogICAgCiAgICAvKioKICAgICAqIEBwYXJhbSBmYWNlcyDjg4DjgqTjgrnjga7pnaLmlbAKICAgICAqIEBwYXJhbSBkaWNlIOODgOOCpOOCueOBruaVsAogICAgICogQHBhcmFtIGMg44GT44Gu5Ye655uu5Lul5LiK44Gu44OA44Kk44K544Gv44KC44GG5LiA5Zue5oyv44KM44KLCiAgICAgKiBAcmV0dXJuIOacn+W+heWApAogICAgICovCiAgICBzdGF0aWMgZG91YmxlIGNhbGMoaW50IGZhY2VzLCBpbnQgZGljZSwgaW50IGMpCiAgICB7CiAgICAgICAgZG91YmxlW10gc2NvcmVzID0gbmV3IGRvdWJsZVtkaWNlICsgMV07CiAgICAgICAgZG91YmxlIHByb2JhYmlsaXR5ID0gTWF0aC5tYXgoMCwgMSAtIChjIC0gMWQpIC8gZmFjZXMpOwoKICAgICAgICAvLyBu5YCL44Gu44OA44Kk44K544KS5oyv44Gj44Gf5pmC44Gu5pyf5b6F5YCk44KS5rGC44KB44Gmc2NvcmVzW25d44Gr5YWl44KM44KLCiAgICAgICAgZm9yIChpbnQgbiA9IDE7IG4gPD0gZGljZTsgbisrKQogICAgICAgIHsKICAgICAgICAgICAgZG91YmxlIHNjb3JlID0gZXhwZWN0ZWRNYXhWYWx1ZShmYWNlcywgbik7CgogICAgICAgICAgICBmb3IgKGludCByZXJvbGwgPSAxOyByZXJvbGwgPCBuOyByZXJvbGwrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc2NvcmUgKz0gc2NvcmVzW3Jlcm9sbF0gKiBiaW5vbWlhbERpc3RyaWJ1dGlvbihuLCByZXJvbGwsIHByb2JhYmlsaXR5KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2NvcmVzW25dID0gc2NvcmUgLyAoMSAtIGJpbm9taWFsRGlzdHJpYnV0aW9uKG4sIG4sIHByb2JhYmlsaXR5KSk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBzY29yZXNbZGljZV07CiAgICB9CiAgICAKICAgIC8qKgogICAgICog5oyH5a6a5Zue44OA44Kk44K544KS5oyv44Gj44Gf5pmC44Gu5Ye655uu44Gu5pyA5aSn5YCk44Gu5pyf5b6F5YCk44KS5rGC44KB44KLCiAgICAgKiBAcGFyYW0gZmFjZXMg44OA44Kk44K544Gu6Z2i5pWwCiAgICAgKiBAcGFyYW0gbnVtIOODgOOCpOOCueOCkuaMr+OCi+aVsAogICAgICogQHJldHVybiDlh7rnm67jga7mnIDlpKflgKTjga7mnJ/lvoXlgKQKICAgICAqLwogICAgc3RhdGljIGRvdWJsZSBleHBlY3RlZE1heFZhbHVlKGludCBmYWNlcywgaW50IG51bSkKICAgIHsKICAgICAgICBkb3VibGUgdmFsdWUgPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IGZhY2VzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB2YWx1ZSArPSAoTWF0aC5wb3coaSwgbnVtKSAtIE1hdGgucG93KGkgLSAxLCBudW0pKSAqIGk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB2YWx1ZSAvIE1hdGgucG93KGZhY2VzLCBudW0pOwogICAgfQoKCiAgICBzdGF0aWMgbG9uZyBiaW5vbWlhbENvZWZmaWNpZW50cyhpbnQgbiwgaW50IGspCiAgICB7CiAgICAgICAgaWYgKG4gPCAwIHx8IG4gPiA2NCB8fCBrIDwgMCB8fCBrID4gbikgdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigpOwogICAgICAgIGlmIChrID09IDAgfHwgayA9PSBuKSByZXR1cm4gMTsKICAgICAgICBpZiAoayA9PSAxIHx8IGsgPT0gbiAtIDEpIHJldHVybiBuOwogICAgICAgIAogICAgICAgIGxvbmdbXSBhcnJheSA9IG5ldyBsb25nW24gKyAxXTsKICAgICAgICBhcnJheVswXSA9IDE7CiAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbjsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgYXJyYXlbaV0gPSAxOwogICAgICAgICAgICBmb3IgKGludCBqID0gaSAtIDE7IGogPj0gMTsgai0tKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhcnJheVtqXSArPSBhcnJheVtqIC0gMV07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFycmF5W2tdOwogICAgfQogICAgCgogICAgc3RhdGljIGRvdWJsZSBiaW5vbWlhbERpc3RyaWJ1dGlvbihpbnQgbiwgaW50IGssIGRvdWJsZSBwKQogICAgewogICAgICAgIHJldHVybiBiaW5vbWlhbENvZWZmaWNpZW50cyhuLCBrKSAqIE1hdGgucG93KHAsIGspICogTWF0aC5wb3coMSAtIHAsIG4gLSBrKTsKICAgIH0KfQo=
N=1, c=5 -> 13.750000
N=2, c=5 -> 21.484375
N=3, c=5 -> 27.061543
N=4, c=5 -> 31.429423
N=5, c=5 -> 35.019871
N=6, c=5 -> 38.067903
N=7, c=5 -> 40.715790
N=8, c=5 -> 43.056198
N=9, c=5 -> 45.152868
N=10, c=5 -> 47.051543