結果
| 問題 | No.76 回数の期待値で練習 |
| コンテスト | |
| ユーザー |
codershifth
|
| 提出日時 | 2015-08-04 01:46:35 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.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 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 2 |
ソースコード
#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
codershifth