結果
問題 | No.76 回数の期待値で練習 |
ユーザー | codershifth |
提出日時 | 2015-08-04 01:46:35 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 27 ms / 5,000 ms |
コード長 | 3,407 bytes |
コンパイル時間 | 1,409 ms |
コンパイル使用メモリ | 164,804 KB |
実行使用メモリ | 11,228 KB |
最終ジャッジ日時 | 2024-07-18 01:10:56 |
合計ジャッジ時間 | 1,883 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 27 ms
11,136 KB |
testcase_01 | AC | 27 ms
11,228 KB |
ソースコード
#include <bits/stdc++.h> typedef long long ll; typedef unsigned long long ull; #define FOR(i,a,b) for(int (i)=(a);i<(b);i++) #define REP(i,n) FOR(i,0,n) #define RANGE(vec) (vec).begin(),(vec).end() using namespace std; class CountExpectationPractice { public: void solve(void) { int T; cin>>T; // sample から各目の出る確率を求めておく vector<double> ans = {0.0, 1.0000000000000000, 1.0833333333333333, 1.2569444444444444, 1.5353009259259260, 1.6915991512345676, 2.0513639724794235}; // p[i] := i+1 が出る確率 vector<double> p(6,0); // Nk がとりうる最大値 int maxN = (int)(1E+6); // n が出るまでサイコロをふる回数の期待値 vector<double> Exp(maxN+1,0); // Exp 更新関数 // p が決定したものとみなして計算する。 function<void(int)> update = [&](int n) { Exp[0] = 0; FOR(i,1,n+1) { // k へは k-(j+1) 時点で j+1 の目を出したときに遷移するので // Exp[k] = 1 + ∑ p[j]*Exp[k-(j+1)] // k>=j+1 Exp[i] = 1.0; REP(j,6) if (i-(j+1) >= 0) Exp[i] += Exp[i-(j+1)] * p[j]; } }; // 二分探索で確立をもとめてやる // ans[k+2] ~ Exp[k+2] は k 番目までの p で確定するので先頭から順に二分探索で確定させていく // O(5*100*5) くらい REP(k,5) { // p = {p1,p2,...,p(k-1),0.0,...,0.0} として考える double l = 0.0; double u = 1.0; double mid = 0.0; // 確率的におかしなケースを計算させないように // 確定した p を使って探索範囲を絞る REP(i,k-1) u -= p[i]; REP(_,100) { // p[k] を更新 p[k] = mid = (l+u)*0.5; // p[0]+...+p[5] = 1.0 より p[5] は残りから計算できる p[5] = 1.0; REP(j,5) p[5] -= p[j]; update(k+2); // Exp[k+2] までを更新 if (Exp[k+2] > ans[k+2]) u = mid; else l = mid; } p[k] = mid; p[5] = 1.0; REP(i,5) p[5] -= p[i]; } // p が確定したので最後の update update(maxN); REP(i,T) { int N; cin>>N; cout<<setprecision(20)<<Exp[N]<<endl; } } }; #if 1 int main(int argc, char *argv[]) { ios::sync_with_stdio(false); auto obj = new CountExpectationPractice(); obj->solve(); delete obj; return 0; } #endif