TopCoder SRM 470 Div1 Medium DrawingLines
問題
上側にn個の点1,2,...,nがあり、下側にn個の点1,2,...,nがある。
上側の点startDot[i]と下側の点startDot[i]が線で結ばれている。
まだ線で結ばれていない上側の点と下側の点を、ランダムに選び線で結ぶ。
全ての点を線で結んだあと、出来ている線の交点の数の期待値を求めよ。
方針
上側のi番目の点から下へ引かれる線と上側のj番目の点から下へ引かれる線が交わる期待値を求める。
それぞれを独立に求めた後で、期待値を足し合わせれば、全ての交点の期待値の数が求められる。
i番目の点から引かれる線とj番目の点から引かれる線が交点をもつ確率は、
元々それぞれの点から最初から線が引かれている場合、そうでない場合に分けて求めることができる。
ソースコード
int p[10001],cnt[10001]; class DrawingLines { public: double countLineCrossings(int n, vector <int> startDot, vector <int> endDot) { memset(p,-1,sizeof(p)); rep(i,n)cnt[i]=1; rep(i,startDot.size()){ p[startDot[i]-1]=endDot[i]-1; cnt[endDot[i]-1]=0; } rep(i,n)cnt[i+1]+=cnt[i]; double ans=0; rep(j,n)rep(i,j){ if(p[i]<0&&p[j]<0)ans+=0.5; else if(p[i]<0)ans+=(cnt[n-1]-cnt[p[j]])*1.0/cnt[n-1]; else if(p[j]<0)ans+=cnt[p[i]]*1.0/cnt[n-1]; else ans+=p[i]<p[j]?0:1; } return ans; } };