シンプルな式で書ける問題。
https://community.topcoder.com/stat?c=problem_statement&pm=15916&rd=17799
問題
整数A,Bが与えられる。
N=2*A+B本のひもがある。
- A本は両端とも赤
- A本は両端とも緑
- B本は両端が赤・緑1つずつ
であるとする。ひもの端は赤と緑が(A+B)個ずるあることになる。
さて、ここでひもの赤い端と緑の端を連結させることを考える。
この連結のさせ方は、(A+B)!通りある。
そうするといくつかの輪ができることになるが、その本数の期待値を求めよ。
解法
赤だけ・緑だけのひもを含まない輪と、含む輪が考えられる。
まず、前者を考える。
今x本の赤・緑両端のひもがあるとき、これらがなす輪の数の期待値をg(x)とする。
うち1本を取り、その緑側の端がどこにつながるかを考える。
赤いひもがA本でその両端が2A個あり、
- 自分自身の赤い端とつなぐ。輪が1個増える。
- 他の赤・緑両端のひもの赤側とつなぐ。実質赤・緑両端のひもが(長さは変わるものの)数としては1個減ったことになる。
- 両端赤のひものどちらかにつなぐ。両端赤のひもが(長さは変わるものの)数としては変わらず、実質赤・緑両端のひもが1個減ったことになる。
よってそれぞれの確率を考えるととなる。
次に、両端が赤のひもと緑のひもを考える。
前者の過程で緑のひもが長くなるかもしれないが、これは緑のひも数には関係ない。
f(x)を、赤のひもとみどりのひもがx組あるときの輪の期待値とする。
まず赤のひもを1つ選びその端が適当な緑の端と結ばれたとする。この時もう一つの端がどこと結ばれるかを考えると、
- 片方の端と同じひものもう片方の端につながり、輪を形成する。これは(2x-1)個の選択肢のうちの1つ。
- 他の緑のひもの端につながる。これは(2x-1)個の選択肢のうちの(2x)通り。この時、最初の緑の余った端点は別の赤いひもとつながる。
よってとなる。
あとはf(0)=g(0)=1から順にf(x),g(x)を求めてf(A)+g(B)を答えればよい。
double F[1010101]; double G[1010101]; class StringRings { public: double expectedRings(int A, int B) { int i; for(i=1;i<=A;i++) F[i]=((F[i-1]+1)+(F[i-1])*2*(i-1))/(2*i-1); for(i=1;i<=B;i++) G[i]=((G[i-1]+1)+(G[i-1])*(2*A+i-1))/(2*A+i); return F[A]+G[B]; } }
まとめ
ちょっと手間取ったけど解き切れてよかった。