H - Revenge of "The Salary of AtCoder Inc." Editorial
by
Shirotsume
\(f(i)\) を、直近に出たサイコロの目が \(i\) であるときこれ以降に得られる給料の期待値とします。
まず、 \(i\) が出たので \(A_i\) 円を貰うことができます。これに次以降のサイコロによる収入を合わせると \(f(i)\) の値を求めることができます。次に出るサイコロの目 \(x\) で場合分けすることで解けます:
\(i \geq x\) のとき:操作はこれで終了します。よって、\(0\) です。
\(i \lt x\)のとき:これ以降もらえる給料の期待値は \(f(x)\) に等しいです。
サイコロの目は等確率で出るので、結局
\(\displaystyle f(i) = A_i + \frac{1}{N} (f(i + 1) + f(i + 2) + \dots + f(N) )\)
として求めることができます。\(f(i)\) を計算するのに必要なのは \(i + 1\) 以降についての \(f\) の値の総和なので、この値を 変数として管理しておくことで \(i\) の大きい方から順に \(f(i)\) を求めることができます。この時の計算量は \(O(N)\) です。
あとは、操作の最初に出た目を考えると、
\(\frac{1}{N} (f(1) + f(2) + \dots + f(N) )\)
が答えとなるので、これを計算すればよいです。全体での計算量も \(O(N)\) となります。
\(A_0 = 0\) を仮定すると、上記の \(f(i)\) の計算式で求めた \(f(0)\) が答えとなるので、実装が楽になります。
posted:
last update: