POJ 2096 Collecting Bugs <概率DP>

题目: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 }
View Code
原文地址:https://www.cnblogs.com/jian1573/p/3245363.html