POJ 2096 Collecting Bugs(概率DP)

题目大意:一个人每天找到一个bug,而一个系统有n个子系统,共s类bug,问要求在每个子系统上找到bug且找到所有类型的bug需要几天。

思路:dp[i][j] 代表找到i个系统出现bug,bug的种类出现j种,离任务目标的期望天数,分情况讨论。

找到一个已有bug的子系统的已出现类型bug:( i * j ) / ( n * s ) * dp [ i ] [ j ]

找到一个已有bug的子系统的未出现类型bug:( i * ( s - j ) / (  n * s ) ) * dp[ i ] [ j + 1 ]

找到一个未出现bug的子系统的已出现类型bug:( ( n -i ) * j )  / ( n * s ) * dp[ i + 1] [ j ] 

找到一个未出现bug的子系统的未出现类型bug:  ( ( n - i ) * ( s - j ) ) / ( n * s ) * dp [ i + 1 ] [ j + 1 ]  

累加移项就可以得到地推关系式。

#include<iostream>
#include<cstdio>
using namespace std;

#define N 1010
double dp[N][N];


int main(){
    int i,j;
    int n,s;

    while(scanf("%d %d",&n,&s)!=EOF){
        dp[n][s]=0;
        for(i=n;i>=0;i--){
            for(j=s;j>=0;j--){
                if(i!=n||j!=s)
                    dp[i][j]=((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)/(n*s-i*j);
            }
        }
        printf("%.4f\n",dp[0][0]);

    }
    return 0;
}


你可能感兴趣的:(DP概率)