期待値に関するセンスがちょっと求められる問題
問題概要
高橋君はテストケースが ケースある Yes/No 判定問題に対して、ソースコードを提出したところ 問で TLE して、残りの 問は正解しました。
そこで「 問については 100ms で正解し、残りの 問に対しては 1900ms で打ち切って Yes/No をランダムに出力するプログラム」を AC がもらえるまで提出し続けることにしました。
AC するまでにかかる時間の期待値を求めよ。
制約
考えたこと
プログラムは毎回、 ms かかることから、AC がもらえるまでの回数の期待値を とすれば、求める期待値は
となることがわかる。よって問題は、AC がもらえるまでに提出する回数の期待値を求める問題へと帰着された。
一般論
以下のことがらは大変有名であり (覚えてしまってもいいくらいだと思う)、直感的にも納得がいく!!!
確率 で成功するミッションを成功するまでトライし続けたとき、トライすることになる回数の期待値は である
これは直感的には「それはそう」という感じである。つまり、例えば確率 で成功するミッションは平均 回で成功する気持ちになれるし、確率 で成功するミッションは平均 回で成功する気持ちになれる。もう少し複雑な例として確率 で成功するミッションは平均 回で成功する (多くの場合 1 回で成功するので 1 をちょっと超えた値になる)。
これを使えば、この問題は簡単で、
- ケース全部通る確率は
となることから、
- AC するまでに試行する回数の期待値は
となる。
#include <iostream> using namespace std; int main() { long long N, M; cin >> N >> M; long long teisyutu_kaisuu = 1LL<<M; long long each_time = 1900LL * M + 100LL * (N - M); cout << each_time * teisyutu_kaisuu << endl; }
証明
一応一般論を 2 通りの方法で証明してみる。
証明 1: 期待値漸化式
この考え方は、期待値 DP を組む時などにもすごく有効なので是非に!!!
求める期待値を とおいて、 を式で表すために場合分けをする。
次の試行で失敗するとき、その確率は である。そして、そこから終わるまでの回数の期待値も なので、最初からの試行回数の期待値は になる。まとめると
次の試行で成功するとき、その確率は である。そしてその時点で終了するので、最初からの試行回数の期待値は になる。まとめると
以上を合わせて、
という方程式が立てられる。これを について解くと、
が得られる。
証明 2: 無限級数
素直に期待値の定義に沿って計算する。期待値の定義とは、 回で終わる確率を として
である。一見非自明なのだが、これは実は
- := 成功までに 回以上かかる確率
として
となる。イメージとしては下図のような感じ。左側が という式を表していて、右側が という式を表している。
よって を求めればよく、これは「 回目までに成功しない確率」なので
となる。よって求める期待値は
と求められる。