結果

問題 No.75 回数の期待値の問題
ユーザー data9824data9824
提出日時 2015-06-23 00:22:41
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 720 ms / 5,000 ms
コード長 1,945 bytes
コンパイル時間 1,257 ms
コンパイル使用メモリ 75,440 KB
実行使用メモリ 11,156 KB
最終ジャッジ日時 2023-09-21 23:54:04
合計ジャッジ時間 3,995 ms
ジャッジサーバーID
(参考情報)
judge14 / judge11
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,380 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 2 ms
4,380 KB
testcase_03 AC 2 ms
4,380 KB
testcase_04 AC 2 ms
4,376 KB
testcase_05 AC 1 ms
4,380 KB
testcase_06 AC 1 ms
4,384 KB
testcase_07 AC 2 ms
4,380 KB
testcase_08 AC 2 ms
4,380 KB
testcase_09 AC 2 ms
4,376 KB
testcase_10 AC 2 ms
4,380 KB
testcase_11 AC 2 ms
4,380 KB
testcase_12 AC 2 ms
4,380 KB
testcase_13 AC 2 ms
4,376 KB
testcase_14 AC 2 ms
4,376 KB
testcase_15 AC 3 ms
4,380 KB
testcase_16 AC 58 ms
5,240 KB
testcase_17 AC 330 ms
7,928 KB
testcase_18 AC 578 ms
10,048 KB
testcase_19 AC 720 ms
11,156 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>

using namespace std;

int main() {
	int k;
	cin >> k;
	// [n][k]: n回目で合計をkにできる場合の数
	vector<vector<double> > patterns(1 + k, vector<double>(1 + k * 6));
	patterns[0][0] = 1;
	for (int n = 1; n <= k; ++n) {
		for (int m = 1; m <= k * 6; ++m) {
			patterns[n][m] = 0;
			for (int i = 1; i <= 6; ++i) {
				if (m - i >= 0) {
					patterns[n][m] += patterns[n - 1][m - i];
				}
			}
		}
	}
	// [n][k]: n回振ったとき合計がkになる確率
	vector<vector<double> > pSumEquals(1 + k, vector<double>(1 + k * 6));
	for (int n = 0; n <= k; ++n) {
		for (int m = 0; m <= k * 6; ++m) {
			pSumEquals[n][m] = patterns[n][m] * pow(1. / 6., n);
		}
	}
	// [n][k]: n回振ったとき合計がk以上になる確率
	vector<vector<double> > pSumGreater(1 + k, vector<double>(1 + k * 6));
	for (int n = 0; n <= k; ++n) {
		for (int m = 0; m <= k * 6; ++m) {
			pSumGreater[n][m] = 0;
			for (int i = m; i <= k * 6; ++i) {
				pSumGreater[n][m] += pSumEquals[n][i];
			}
		}
	}
	// [n][k]: n-1回目で合計がk未満であり、n回目で合計がkを超える確率
	vector<vector<double> > pSumOver(1 + k, vector<double>(1 + k * 6));
	for (int n = 1; n <= k; ++n) {
		for (int m = 0; m <= k * 6; ++m) {
			pSumOver[n][m] = 0;
			for (int i = 0; i <= m - 1; ++i) {
				if (m + 1 - i >= 0 && m + 1 - i < 1 + k * 6) {
					pSumOver[n][m] += pSumEquals[n - 1][i]
						* pSumGreater[1][m + 1 - i];
				}
			}
		}
	}
	double lower = 0;
	double upper = k * 6;
	while (upper - lower > 1E-5) {
		double e = (lower + upper) / 2;
		double solution = 0;
		for (int i = 1; i <= k; ++i) {
			solution += i * pSumEquals[i][k];
		}
		for (int i = 1; i <= k; ++i) {
			solution += (i + e) * pSumOver[i][k];
		}
		solution -= e;
		if (solution > 0.0) {
			lower = e;
		} else {
			upper = e;
		}
	}
	cout << fixed << setprecision(4) << lower << endl;
	return 0;
}
0