Collecting Bugs(POJ 2096)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35558510/article/details/90040107

一个软件有s个子系统,会产生n种bug。某人一天发现一个bug,这个bug属于一个子系统,属于一个分类。每个bug属于某个子系统的概率是1/s,属于某种分类的概率是1/n 。则每个子系统中找到至少一个bug,并且每个类别至少有一个bug所需天数的期望?

dp[i][j]表示已经找到i种bug,j个系统的bug,达到目标状态的天数的期望.

反解dp[i][j]可得

 

dp[i][j]可以转化成以下四种状态

  • dp[i][j],发现一个bug属于已经有的i个分类和j个系统。概率为(i/n)*(j/s)
  • dp[i][j+1],发现一个bug属于已有的分类,不属于已有的系统.概率为 (i/n)*(1-j/s)
  • dp[i+1][j],发现一个bug属于已有的系统,不属于已有的分类,概率为 (1-i/n)*(j/s)
  • dp[i+1][j+1],发现一个bug不属于已有的系统,不属于已有的分类,概率为 (1-i/n)*(1-j/s)
#include <iostream>
#include <stdio.h>

using namespace std;

#define MAXN 1002
int N;//类别数

int S;//系统数

double dp[MAXN][MAXN]; //1001+1

double solve() {
    for (int i = N; i >= 0; i--) {
        for (int j = S; j >= 0; j--) {
            if (i == N and j == S) {
                continue;
            }
            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);
        }
    }
    return dp[0][0];
}

int main() {
    cin >> N >> S;
    printf("%.4lf\n", solve());
}

猜你喜欢

转载自blog.csdn.net/qq_35558510/article/details/90040107