#include <cstdio>
const int maxn = 1E3 + 10;
double dp[maxn][maxn];
int n, s, ns;
int main(int argc, char const *argv[])
{
scanf("%d%d", &n, &s);
ns = n * s;
dp[n][s] = 0;
for (int i = n; i >= 0; i--)
for (int j = s; j >= 0; j--)
if (i == n && j == s) continue;
else dp[i][j] = ( ns + (n - i) * j * dp[i + 1][j] + i * (s - j) * dp[i][j + 1] + (n - i) * (s - j) * dp[i + 1][j + 1] ) / ( ns - i * j );
printf("%.4lf\n", dp[0][0]);
return 0;
}
dp[i][j]表示已经找到i种bug,并存在于j个子系统中,要达到目标状态的天数的期望。
显然,dp[n][s]=0,因为已经达到目标了。而dp[0][0]就是我们要求的答案。
dp[i][j]状态可以转化成以下四种:
dp[i][j] 发现一个bug属于已经找到的i种bug和j个子系统中
dp[i+1][j] 发现一个bug属于新的一种bug,但属于已经找到的j种子系统
dp[i][j+1] 发现一个bug属于已经找到的i种bug,但属于新的子系统
dp[i+1][j+1]发现一个bug属于新的一种bug和新的一个子系统
以上四种的概率分别为:
p1 = i*j / (n*s)
p2 = (n-i)*j / (n*s)
p3 = i*(s-j) / (n*s)
p4 = (n-i)*(s-j) / (n*s)