POJ 2096 Collecting Bugs

Collecting Bugs

首个概率DP类题目。题意: 一个软件有S个子系统,会产生n中bug

某人一天发现一个bug,这个bug属于一个子系统并且属于一个分类。每个bug属于某个子系统的概率是1/s,属于某个分类的概率为1/n,求发现n中bug,每个子系统都发现bug的天数的期望。

全期望的公式:E(Y) = E(E(Y|x)) = sgm(P(X=xi)E(Y|X = xi)) ;粘贴公式不方便= =

设dp[i][j] 表示已经找到i种bug,j个子系统的bug,达到目标状态的天数的期望,由于我们可以很容易确定最后的状态,所以逆推。dp[n][s] = 0 ; 答案就是dp[0][0] ;

dp[i][j] 可以转化为如下状态:

(1)如果发现的一个bug为已有的i个分类和j个子系统,概率为(i/n) * (j/s);

(2)如果发现的一个bug为已有的分类,但不属于已有系统,概率为(i/n) * (1 - j/s) ;

(3)如果发现的一个bug不是已有的分类,但是已有的系统,概率为(1- i/n) * (j/s) ;

(4)如果发现的一个bug既不是已有的分类,也不是已有的系统中的,概率为(1 - i/n) * (1 - j/s) ;

然后我们就结合全期望公式整理就可以很容易得到转移方程。代码如下:

/*
    author    : csuchenan
    prog      : POJ 2096
    algorithm : probability DP 
    csuchenan	2096	Accepted	8068K	172MS	C++	651B	
*/
#include <cstdio>
#include <cstring>
const int maxn = 1005 ;

double dp[maxn][maxn] ;
int main(){
    int n , s ;
    scanf("%d%d" , &n , &s) ;
    dp[n][s] = 0 ;
    for(int i = n ; i >= 0 ; i --){
        for(int j = s ; j >= 0 ; j  --){
            if(i == n && j == s)
                continue ;
             dp[i][j] = (i * (s-j) * dp[i][j + 1]
                + (n - i) * j * dp[i + 1][j]
                + (n - i) * (s - j) * dp[i + 1][j + 1]
                + n * s )/(n * s - i * j) ;
        }
    }
    printf("%.4f\n" , dp[0][0]) ;
    return 0 ;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值