poj2096
题意:
一个软件有s个子系统,会产生n种bug 某人一天发现一个bug,这个bug属于一个子系统,属于一个分类 每个bug属于某个子系统的概率是1/s,属于某种分类的概率是1/n 问发现n种bug,每个子系统都发现bug的天数的期望。
——————————————————————————————————————————————————————
f[i][j]:从找到i种j个系统的bug到找到n种s个系统的bug需要的天数。
明显f[n][s]==0
那么从f[i][j]找一天,找到一个bug,可能产生四中情况:
1、还是i种j系统,概率(i*j)/(n*s)
2、i+1种j系统,概率((n-i)*j)/(n*s)
3、i种j+1系统,概率((s-j)*i)/(n*s)
4、i+1种j+1系统,概率((n-i)*(s-j))/(n*s)
所以逆推
f[i][j]=(i*j)/(n*s)*f[i][j]+((n-i)*j)/(n*s)*f[i+1][j]+((s-j)*i)/(n*s)*f[i][j+1]+((n-i)*(s-j))/(n*s)*f[i+1][j+1]+1
化简后得到:
f[i][j]=((n-i)*j*f[i+1][j]+(s-j)*i*f[i][j+1]+(n-i)*(s-j)*f[i+1][j+1]+n*s)/(n*s-i*j)
—————————————————————————————————————————————————————
1 #include<cstdio> 2 using namespace std; 3 const int maxn=1010; 4 int n,s; 5 double f[maxn][maxn]; 6 7 int main() 8 { 9 scanf("%d%d",&n,&s); 10 11 f[n][s]=0; 12 for(int i=n;i>=0;--i) 13 for(int j=s;j>=0;--j) 14 { 15 if(i==n&&j==s)continue; 16 f[i][j]=((n-i)*j*f[i+1][j]+(s-j)*i*f[i][j+1]+(n-i)*(s-j)*f[i+1][j+1]+n*s)/(n*s-i*j); 17 } 18 printf("%.4lf\n",f[0][0]); 19 20 return 0; 21 }