poj-2096-期望/dp

http://poj.org/problem?id=2096

    有n种病毒,s个服务器,每天等概率的在某个服务器上发现某一种病毒,问发现所有种类病毒且覆盖所有的服务器的期望天数。

利用全期望公式可以将期望分解为子期望的加权和,权值就是子期望发生的概率Pi,注意SUM{ Pi }=1; 

假如我们已经完成了(i,j),目标是(n,s),那么下一天可能是(i,j) ,(i+1,j) ,(i,j+1) ,(i+1,j+1)  对应的Pi分别是 p1=(i/n)*(j/s)  p2=(1-i/n)*(j/s)  p3=(i/n)*(1-j/s)  p4=(1-i/n)*(1-j/s)

设f(i,j)为完成了(i,j)距离目标的期望,那么有f(i,j)=p1*(f(i,j)+1)+p2*(f(i+1,j)+1)+p3*(f(i,j+1)+1)+p4*(f(i+1,j+1)+1) | f(n,s)=0 ,移项解出f(i,j)即可。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<queue>
 4 #include<cstdio>
 5 #include<stack>
 6 #include<set>
 7 #include<map>
 8 #include<cmath>
 9 #include<ctime>
10 #include<time.h> 
11 #include<algorithm>
12 using namespace std;
13 #define mp make_pair
14 #define pb push_back
15 #define debug puts("debug")
16 #define LL long long 
17 #define pii pair<int,int>
18 #define eps 1e-12
19 
20 double f[1100][1100];
21 int main()
22 {
23     int n,m,i,j,k,t;
24     cin>>n>>m;
25     for(i=n;i>=0;--i){
26         for(j=m;j>=0;--j){
27             if(i==n&&j==m) continue;
28             double p1=(double)i*j,p2=(double)j*(n-i),
29             p3=(double)i*(m-j),p4=(double)(n-i)*(m-j);
30             p1/=(1.0*n*m);p2/=(1.0*n*m);p3/=(1.0*n*m);p4/=(1.0*n*m);
31             f[i][j]=p1+p2*(f[i+1][j]+1)+p3*(f[i][j+1]+1)+
32             p4*(f[i+1][j+1]+1);
33             f[i][j]/=(1.0-p1);
34         }
35     }
36     printf("%.4f\n",f[0][0]);
37     return 0; 
38 }

 

posted @ 2018-05-02 11:25  *zzq  阅读(218)  评论(0编辑  收藏  举报