最初Hardの問題と勘違い→Mediumが解けず時間浪費→ラスト5分で誤差に気づく→終了後Hardがあっさり通った。
前回のVK Cupといいひどすぎる。
http://yukicoder.me/problems/325
問題
A君B君の2人は1~1000の異なる整数値が書かれたN枚のカードA[i],B[i]を持っている。
2人は手持ちのカードを1枚出す、というゲームをN回繰り返す。
大きな数値の書かれた方が勝ちとなり、2枚の数値の合計分の得点を得る。
なお、2人のカードの出し方は以下の通りである。
- 手持ちのカードが1枚の時はそれを出す。
- 手持ちのカードが2枚以上の時:
- A君は確率Pa、B君はPbで手持ちの最小値のカードを出す。
- A君は確率(1-Pa)、B君は(1-Pb)で手持ちのうち最小値以外のカードのいずれかを等確率で出す。
最終的にA君が取得得点で勝つ確率を求めよ。
解法
誤差が0.5%まで許容されるので、シミュレーションを繰り返せばばよい。
シミュレーションではなく、精度高くやろうとするとHardより難しいかも。
int N,T; double P[2]; int A[30],B[30]; int win,tot; vector<int> getrandvec(double p) { int i,x; vector<int> v,r; FOR(i,N) v.push_back(i); FOR(i,N-1) { double d = rand()*1.0/RAND_MAX; if(d<p) x=0; else x=1+(N-1-i)*(d-p)/(1-p); r.push_back(v[x]); v.erase(v.begin()+x); } r.push_back(v[0]); return r; } void solve() { int i,j,k,l,r,x,y; string s; cin>>N>>P[0]>>P[1]; FOR(i,N) cin>>A[i], T+=A[i]; FOR(i,N) cin>>B[i], T+=B[i]; sort(A,A+N); sort(B,B+N); srand(time(NULL)); FOR(i,200000) { tot++; vector<int> VA,VB; VA=getrandvec(P[0]); VB=getrandvec(P[1]); x=0; FOR(y,N) if(A[VA[y]]>B[VB[y]]) x+=A[VA[y]]+B[VB[y]]; if(x>T/2) win++; } _P("%.12lf\n",1.0*win/tot); }
まとめ
解けなくても先に後ろの問題読むべきだなぁ。