SRM練習 626 div1 easy
問題要約:Aはa個の1からbまでの整数が同様に確からしい確率で出るサイコロを持っている。Bはc個の1からdまでの整数が同様に確からしい確率で出るサイコロを持っている。今A,Bがすべてのサイコロをふって自分のサイコロの総和Sa,Sbを求めたところSa>Sbであった。このときSaの期待値を求めよ。
確率DPの部分はできたけど、条件付き確率と期待値計算のところができなかった。
Aが勝つ確率 PA = Σ_{i>j} (Aの和がiとなる確率)*(Bの和がjとなる確率)
であるので、Aのサイコロの和がxでBに勝つ確率P(x)とすると、
P(x) = {Σ_{x>j} (Aの和がxとなる確率)*(Bの和がjとなる確率)} / PA
Aが勝つ時のサイコロの和の期待値Eは
E = Σ x * P(x)
で求まる。
(最初、Bobのサイコロの和を固定して〜とかやっていたら意味不明なことをしてしまった)
#include <cstdio> #include <algorithm> #include <vector> #include <string> using namespace std; double dpA[51][51*51]; double dpB[51][51*51]; class FixedDiceGameDiv1{ public: double getExpectation(int a, int b, int c, int d){ if(a*b <= c) return -1.0; for(int j=1; j <= b; j++) dpA[1][j] = 1.0 / (double)b; for(int j=1; j <= d; j++) dpB[1][j] = 1.0 / (double)d; for(int i = 2; i <= a; i++) for(int j=1; j<=a*b; j++) for(int k=1; k<=b; k++){ if(j-k>=0) dpA[i][j] += dpA[i-1][j-k]/b; } for(int i = 2; i <= c; i++) for(int j=1; j<=c*d; j++) for(int k=1; k<=d; k++){ if(j-k>=0) dpB[i][j] += dpB[i-1][j-k]/d; } double ans = 0; double P = 0; for(int SA=a; SA<=a*b; SA++) for(int SB=c; SB<=c*d; SB++) if(SA > SB){ P += dpA[a][SA] * dpB[c][SB]; } for(int SA=a; SA<=a*b; SA++) for(int SB=c; SB<=c*d; SB++) if(SA > SB){ double p = dpA[a][SA] * dpB[c][SB]; ans += SA * (p/P); } return ans; } };