题意ios
有s个系统,n种bug,小明天天找出一个bug,多是任意一个系统的,多是任意一种bug,便是某一系统的bug几率是1/s,是某一种bug几率是1/n。 求他找到s个系统的bug,n种bug,须要的天数的指望。ide
分析spa
题意很难懂··真的很难懂···code
基础的几率dp。blog
令f[i][j]为当前已经找出i种bug,j个系统的,要到达目标状态(n,s)的指望天数。显然f[n][s]=0;string
考虑一下状态的转移it
1.转移到[i+1][j]的几率为(n-i)/n*j/sio
2.转移到[i][j+1]的几率为i/n*(s-j)/sevent
3.转移到[i+1][j+1]的几率为(n-i)/n*(s-j)/sclass
4.转移到[i][j]的几率为i/n*j/s
f[i][j]=(n-i)/s*j/s*f[i+1][j]+i/n*(s-j)/s*f[i][j+1]+f[i+1][j+1]*(n-i)/n*(s-j)/s+f[i][j]*i/n*j/s
移一下项
(1-i/n*j/s)*f[i][j]=(n-i)/s*j/s*f[i+1][j]+i/n*(s-j)/s*f[i][j+1]+f[i+1][j+1]*(n-i)/n*(s-j)/s
而后把左边的除过去得
f[i][j]=((n-i)/s*j/s*f[i+1][j]+i/n*(s-j)/s*f[i][j+1]+f[i+1][j+1]*(n-i)/n*(s-j)/s)/(1-i/n*j/s)
而后整理一下得
f[i][j]=(f[i+1][j]*(n-i)*j+f[i][j+1]*(s-j)*i+f[i+1][j+1]*(n-i)*(s-j)+n*s)/(n*s-i*j);
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 6 using namespace std; 7 const int maxn=1000+100; 8 double f[maxn][maxn]; 9 int n,s; 10 11 int main(){ 12 while(scanf("%d%d",&n,&s)!=EOF){ 13 memset(f,0,sizeof(f)); 14 for(int i=n;i>=0;i--){ 15 for(int j=s;j>=0;j--){ 16 if(i==n&&j==s) 17 continue; 18 f[i][j]=(f[i+1][j]*(n-i)*j+f[i][j+1]*(s-j)*i+f[i+1][j+1]*(n-i)*(s-j)+n*s)/(n*s-i*j); 19 // f[i][j]=(f[i+1][j]*(double)(n-i)*j/(n*s)+f[i][j+1]*(double)i*(s-j)/(s*n)+f[i+1][j+1]*(n-i)*(s-j)/(n*s))/(1-(double)i/n*(double)j/s); 20 } 21 } 22 printf("%.4f\n",f[0][0]); 23 } 24 return 0; 25 }