【题目】F. Strongly Connected Tournament
【题意】给定n个点(游戏者),每轮游戏进行下列操作:
1.对于游戏者i和j(i<j),有p的概率i赢j(反之j赢i),连边从赢者向输者,从而得到一个有向完全图,这些点视为进行了一轮游戏。
2.对于其中点数>1的强连通分量再次进行过程1,直至不存在点数>1的强连通分量为止。
给定n和p,求所有点进行的游戏轮数之和,2<=n<=2000。
【算法】数学概率,期望DP
【题解】参考:官方题解Hello 2018 -- Tutorial,写得很详细。
容易发现答案只和点数有关,设ans(s)表示s个点进行游戏的总轮数,ans(0)=ans(1)=0,根据全期望公式:
ans(s) = Σ strong(i) * cp(s,i) * [ i*(s-i) + i*(i-1)/2 + ans(i) + ans(s-i) ] , 1<=i<=s
其中strong(i)表示i个点形成强连通分量的概率,cp(s,i)表示s个点中有i个点的集合输给集合外的所有人的概率,strong(i)*cp(s,i)的含义是图缩点成DAG后拓扑序上最后一个点来自的强连通分量大小为i的概率。(?)
后面部分是这种情况下的期望值。首先集合外所有点赢了集合内所有点共i*(s-i)局游戏,集合内部共i*(i-1)/2局游戏,集合内部之后还要进行的游戏数是ans[i],集合外含本轮总共游戏数是ans[s-i]。
上面的公式右边含有ans(s),需要移项。
接下来是strong(s)的计算,strong(1)=1,根据全概率公式:
strong(s)=1-Σstrong(i)*cp(s,i),1<=i<s (?)
接下来是cp(s,i)的计算,cp(s,0)=1,根据全概率公式:
cp(s,i) = cp(s-1,i) * (1-p)^i + cp(s-1,i-1) * p^(s-i)
复杂度O(n^2)。