题目描述
传送门
题意:
一个软件有s个子系统,会产生n种bug
某人一天发现一个bug,这个bug属于一个子系统,属于一个分类
每个bug属于某个子系统的概率是1/s,属于某种分类的概率是1/n
问发现n种bug,每个子系统都发现bug的天数的期望
题解
令f(i,j)表示发现了i种bug,属于j个子系统到最后的期望天数
显然f(n,s)=0
对于f(i,j),dp方程为
f(i,j)=(f(i,j)+1)∗in∗js+(f(i+1,j)+1)∗(1−in)∗js+(f(i,j+1)+1)∗(1−js)∗in+(f(i+1,j+1)+1)∗(1−in)∗(1−js)
整理将f(i,j)移项到方程的左边,就可以dp了
目标f(0,0)
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,s;
double f[1005][1005];
int main()
{
scanf("%d%d",&n,&s);
for (int i=n;i>=0;--i)
for (int j=s;j>=0;--j)
{
if (i==n&&j==s) continue;
f[i][j] += ( f[i+1][j] + 1.0 )*( 1.0 - (double)i/(double)n )*( (double)j/(double)s );
f[i][j] += ( f[i][j+1] + 1.0 )*( (double)i/(double)n )*( 1.0 - (double)j/(double)s );
f[i][j] += ( f[i+1][j+1] + 1.0 )*( 1.0 - (double)i/(double)n )*( 1.0 - (double)j/(double)s );
f[i][j] += ( (double)i/(double)n )*( (double)j/(double)s );
f[i][j] /= ( 1.0 - ( (double)i/(double)n )*( (double)j/(double)s ) );
}
printf("%.4lf\n",f[0][0]);
}