题目:http://poj.org/problem?id=2096
题意:一个软件有 s 个子系统,存在 n 种 bug。某人一天能找到一个 bug。
问,在这个软件中找齐 n 种 bug,并且每个子系统中至少包含一个 bug 的时间的期望值(单位:天)。
注意:bug 是无限多的,每个 bug 属于任何一种 bug 的概率都是 1/n;出现在每个系统是等可能的,为 1/s。
思路:令 f[i][j] 表示已经找到了 i 种 bug,且 j 个子系统至少包含一个 bug,距离完成目标需要的时间的期望。
目标状态是 f[0][0]~
转移方程: f[i][j] = i/n*j/s*f[i][j] + i/n*(s-j)/s*f[i][j+1] + (n-i)/n*j/s*f[i+1][j] + (n-i)/n*(s-j)/s*f[i+1][j+1] + 1
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 double p0,p1, p2, p3, dp[1010][1010]; 6 int main( ) 7 { 8 int n, s; 9 while(scanf("%d%d", &n, &s)!=EOF){ 10 memset(dp, 0, sizeof dp); 11 for( int i=n; i>=0; --i ){ 12 for( int j=s; j>=0; --j ){ 13 if(i==n&&j==s)continue; 14 p0=1.0*i/n*j/s; 15 p1=1.0*i/n*(s-j)/s; 16 p2=1.0*(n-i)/n*j/s; 17 p3=1.0*(n-i)/n*(s-j)/s; 18 dp[i][j]=p1*dp[i][j+1]+p2*dp[i+1][j]+p3*dp[i+1][j+1]+1; 19 dp[i][j]/=(1-p0); 20 21 } 22 } 23 printf("%.4f ", dp[0][0]); 24 } 25 return 0; 26 }