結果
問題 |
No.75 回数の期待値の問題
|
ユーザー |
![]() |
提出日時 | 2015-08-02 23:15:54 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 2 ms / 5,000 ms |
コード長 | 2,115 bytes |
コンパイル時間 | 1,311 ms |
コンパイル使用メモリ | 160,268 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-07-18 00:53:19 |
合計ジャッジ時間 | 2,332 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 16 |
ソースコード
#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 CountExpectationProblem { public: // 残りの数値 k から終了までのサイコロをふる回数の期待値を Exp(k) とする。 // このとき // // * Exp(0) = 0 // * Exp(k) = Exp(K) (k < 0) (K を超えたら 0 にリセットされるので) // * Exp(k) = 1 + (Exp(k-1)+...+Exp(k-6))/6 (k>0) // // この連立方程式から Exp(K) を計算すれば良い // // Exp(K) = x として漸化式を計算する。 double F(int K, double x) { vector<double> Exp(K+1,0); FOR(k,1,K+1) { Exp[k] = 1.0; for (int i = 1; i <= 6; ++i) Exp[k] += ((k-i>=0)? Exp[k-i] : x)/6.0; // k<0 のときは x (Exp(K)の近似値) を使う } return Exp[K]; } void solve_binserach(void) { int K; cin>>K; // // 漸化式より Exp(k) は初項 x = Exp(K) の関数 F(k,x) = Exp(k) とみなせる。 // y = F(x) = F(K,x) とすると // // F(0) > 0 // F(B) - B < 0 (B は十分大きな数値,k=1 から帰納的に示せる) // // なので二分探索で F(x)=x なる x を求められる。 double low = 0.0; double high = 10E+6; REP(i,100) { double mid = (low+high)*0.5; if (F(K, mid) > mid) low = mid; else high = mid; } cout<<setprecision(20)<<(low+high)*0.5<<endl; } void solve(void) { solve_binserach(); } }; #if 1 int main(int argc, char *argv[]) { ios::sync_with_stdio(false); auto obj = new CountExpectationProblem(); obj->solve(); delete obj; return 0; } #endif