POJ2096-Collecting Bugs-概率DP

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

题意:传送门

 原题目描述在最下面。
 n种类bug,属于s个子系统
 每天都会发现一个bug
 问发现n种bug,且每个系统中都有bug的期望天数

思路:

状态表示:

dp[i][j]表示已经发现i种bug,j个子系统有bug,达到目标状态还需要的期望天数
dp[i][j]可以转化为4种情况:

dp[i][j]发现一个已有的bug概率:i/n*j/s
dp[i+1][j]发现一个bug属于新的种类概率:(n-i)/n*j/s
dp[i][j+1]发现一个属于新的子系统概率:i/n*(s-j)/s
dp[i+1][j+1]发现一种新的bug且属于新的子系统概率:(n-i)/n*(s-j)/s

状态转移方程:

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

AC代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
const int N = 1e3 + 7;
const int INF = 0x3f3f3f3f;
double dp[N][N];
int n, s;
/*
n种类bug,属于s个子系统
每天都会发现一个bug
问发现n种bug,且每个系统中都有bug的期望天数

dp[i][j]表示已经发现i种bug,j个子系统有bug,达到目标状态还需要的期望天数
dp[i][j]可以转化为4种情况:

dp[i][j] 发现一个已有的bug概率:i/n*j/s
dp[i+1][j]发现一个bug属于新的种类概率:(n-i)/n*j/s
dp[i][j+1]发现一个属于新的子系统概率:i/n*(s-j)/s
dp[i+1][j+1]发现一种新的bug且属于新的子系统概率:(n-i)/n*(s-j)/s

状态转移方程:
dp[i][j] = (1+dp[i+1][j]*(n-i)/n*j/s+dp[i][j+1]*i/n*(s-j)/s+dp[i+1][j+1]*(n-i)/n*(s-j)/s)/(1-i/n*j/s)
*/
int main(int argc, char const *argv[]){
  while(~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] = (n*s + dp[i+1][j]*(n-i)*j + dp[i][j+1]*i*(s-j) + dp[i+1][j+1]*(n-i)*(s-j))/(n*s-i*j);
      }
    }
    printf("%.4f\n", dp[0][0]);
  }
  return 0;
}


原题目描述:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/81163769