poj 2096 Collecting Bugs (概率dp)

/*
dp求期望
逆着递推求解
题意:
   一个软件有s个子系统,会产生n种bug
   某人一天发现一个bug,这个bug属于一个子系统,属于一个分类
   每个bug属于某个子系统的概率是1/s,属于某种分类的概率是1/n
   问发现n种bug,每个子系统都发现bug的天数的期望。
求解:
    dp[i][j]表示已经找到i种bug,j个系统的bug,达到目标状态的天数的期望
    dp[n][s]=0,dp[0][0]为所求答案
    dp[i][j]由四种状态转化而来
    1:dp[i][j] 发现一个状态已有i个分类j个系统 概率p1=i/n*j/s
    2: dp[i+1][j]  发现有未属于这个分类,但属于这个系统的bug 概率p2=(1-i/n)*j/s
    3: dp[i][j+1] 发现属于这个系统,但不属于这个分类的bug 概率p3=i/n*(1-j/s)
    4: dp[i+1][j+1] 发现为属于这个系统且不属于这个分类的bug 概率p4=(1-i/n)*(1-j/s)

    所以: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]=(dp[i+1][j]*(n*j-i*j)+dp[i][j+1]*(i*s-i*j)+dp[i+1][j+1]*(n*s-j*n-i*s+i*j)+n*s)/(n*s-i*j);
*/
# include <stdio.h>
# include <algorithm>
# include <string.h>
# include <iostream>
using namespace std;
double dp[1010][1010];
int main()
{
    int n,s,i,j;
    while(~scanf("%d%d",&n,&s))
    {
        // memset(dp,0,sizeof(dp));
        dp[n][s]=0;
        for(i=n; i>=0; i--)
        {
            for(j=s; j>=0; j--)
            {
                if(i==n&&j==s)
                    continue;
                dp[i][j]=(dp[i+1][j]*(n*j-i*j)+dp[i][j+1]*(i*s-i*j)+dp[i+1][j+1]*(n*s-j*n-i*s+i*j)+n*s)/(n*s-i*j);
            }
        }
        printf("%.4lf\n",dp[0][0]);
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值