[poj2096]Collecting Bugs[概率dp]

【转】dp求期望的题。题意:一个软件有s个子系统,会产生$n$种$bug$。

某人一天发现一个$bug$,这个$bug$属于某种$bug$,发生在某个子系统中。

求找到所有的$n$种$bug$,且每个子系统都找到$bug$,这样所要的天数的期望。

 

需要注意的是:$bug$的数量是无穷大的,所以发现一个$bug$,出现在某个子系统的概率是$1/s$,属于某种类型的概率是$1/n$。

 

解法:$dp[i][j]$表示已经找到$i$种$bug$,并存在于$j$个子系统中,要达到目标状态的天数的期望。

显然,$dp[n][s]=0$,因为已经达到目标了。而$dp[0][0]$就是我们要求的答案。$dp[i][j]$状态可以转化成以下四种:

  $dp[i][j]$    发现一个$bug$属于已经找到的$i$种$bug$和$j$个子系统中

  $dp[i+1][j]$    发现一个$bug$属于新的一种$bug$,但属于已经找到的$j$种子系统

  $dp[i][j+1]$    发现一个$bug$属于已经找到的$i$种$bug$,但属于新的子系统

  $dp[i+1][j+1]$    发现一个$bug$属于新的一种$bug$和新的一个子系统

 

以上四种的概率分别为:

  $p1={i*j}/{n*s}$;

  $p2={n-i}*j/{n*s}$;

  $p3={i*(s-j)}/{n*s}$;

  $p4={(n-i)*(s-j)}/{n*s}$

 

又有:期望可以分解成多个子期望的加权和,权为子期望发生的概率,即

  $E(aA+bB+...) = aE(A) + bE(B) +...$

所以:

  ${dp[i,j]=p1*dp[i,j]+p2*dp[i+1,j]+p3*dp[i,j+1]+p4*dp[i+1,j+1]+1}$;

整理得:

  ${dp[i,j]=\frac{1+p2*dp[i+1,j]+p3*dp[i,j+1]+p4*dp[i+1,j+1]}{1-p1 }}$

 

  ${=\frac{n*s+(n-i)*j*dp[i+1,j]+i*(s-j)*dp[i,j+1]+(n-i)*(s-j)*dp[i+1,j+1]}{n*s-i*j}}$

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <cmath>
 7 #include <ctime>
 8 
 9 using namespace std;
10 
11 double    m,f[1100][1100];
12 
13 int main()
14 {
15     int    n,s,i,j;
16 
17     scanf("%d%d",&n,&s);
18     m=n*s;
19     f[n][s]=0.0;
20     for(i=n;i>=0;--i)
21     {
22         for(j=s;j>=0;--j)
23         {
24             if(i==n && j==s)continue;
25             f[i][j]=(m+(n-i)*j*f[i+1][j]+i*(s-j)*f[i][j+1]+(n-i)*(s-j)*f[i+1][j+1])/(m-i*j);
26         }
27     }
28     printf("%.4f\n",f[0][0]);
29     return 0;
30 }

 

转载于:https://www.cnblogs.com/Gster/p/5090526.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值