【poj2096】Collecting Bugs

题目描述

有s个系统,n种bug,小明每天找出一个bug,可能是任意一个系统的,可能是任意一种bug,即是某一系统的bug概率是1/s,是某一种bug概率是1/n。

求他找到s个系统的bug,n种bug,需要的天数的期望。

输入

一行两个数分别表示n和s。
输出

一行一个数,表示天数的期望。
样例输入

1 2
样例输出

3.0000

 



题解

设 dp[ i ][ j ] 表示已经找到了 i 种bug,在 j 个系统里。考虑下一天,分为4种情况:

1.找到的bug不在前 i 种bug里,在 j 个系统里。此种情况概率 p1 = (n - i)*( j ) / ( n*s );

2.找到的bug在前 i 种bug里,不在 j 个系统里。这种情况概率p2 = i*(s-j) / ( n*s );

3.找到的bug不在前 i 种bug里,也不在 j 个系统里。这种情况概率p3 = (n-i) * (s-j) / ( n*s );

4.找到的bug在前 i 种bug里,也在 j 个系统里。这种情况概率p4 = (i*j) / ( n*s );

所以我们可以列出式子:dp[ i ][ j ] = dp[ i+1 ][ j ] * p1 + dp[ i ][ j+1 ] * p2 + dp[ i+1 ][ j+1 ] * p3+ dp[ i ][ j ] * p4 +1

移项: dp[ i ][ j ] = ( dp[ i+1 ][ j ] * p1 + dp[ i ][ j+1 ] * p2 + dp[ i+1 ][ j+1 ] * p3 + 1 ) / ( 1 - i * j / s * n )

化简得:dp[ i ][ j ] = ( dp[ i+1 ][ j ] * ( n - i ) * j + dp[ i ][ j + 1 ] * ( s - j ) * i + dp[ i + 1 ][j + 1 ] * ( s - j ) * ( n - i ) + n * s ) / ( n * s - i * j )

 

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long

const int maxn=1000+5;

int n,s;
double dp[maxn][maxn];

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

 

posted @ 2018-08-14 20:25  rld  阅读(139)  评论(0编辑  收藏  举报