zoukankan      html  css  js  c++  java
  • poj 2096 Collecting Bugs

    题意:

    一个公司的系统有n种bug,s个子系统。

    一个人找一个bug需要找一天。

    找到每种是等概率的,找到一个子系统是等概率的。

    现在,他需要在每个子系统中找到一个bug,并且找到n种bug,问期望的天数。

    思路:

    概率dp入门题,一般来说,期望是逆推的。

    设dp[i][j]表示找到了i种bug,找完j个系统之后还需要的天数。

    显然dp[n][s] = 0,因为不需要找了。

    于是向前逆推,从明天推到今天,显然明天花的时间要多一天:

    今天找到i种bug,找完了j种系统,可能有几种情况

    dp[i+1][j],明天找到了i+1种bug,找完j个子系统,概率是(n-i) * j / (s*n);

    dp[i][j+1],明天找到了i种bug,找完j+1个子系统,概率是i * (s-j) / (s*n);

    dp[i+1][j+1],明天找到了i+1种bug,找完j个子系统,概率是(n-i) * (s-j) / (s*n);

    dp[i][j],明天找到了i种bug,找完j个子系统,概率是i * j / (s*n);

    所以,就有如下的期望递推式子:

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

    整理之后得到:

    dp[i][j] = (dp[i][j] * i * j + dp[i+1][j+1] * i * (s-j) +dp[i][j+1] * i * (s-j) + dp[i+1][j] * (n-i) * j + s * n) / (s * n - i * j)。

    倒着dp就行了,答案就是dp[0][0]。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 const int N = 1e3 + 5;
     6 double dp[N][N];
     7 int main()
     8 {
     9     int n,s;
    10     scanf("%d%d",&n,&s);
    11     dp[n][s] = 0;
    12     for (int i = n;i >= 0;i--)
    13     {
    14         for (int j = s;j >= 0;j--)
    15         {
    16             if (i == n && j == s) continue;
    17             double &ans = dp[i][j];
    18             ans = (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) / (n*s-i*j);
    19         }
    20     }
    21     printf("%.4f
    ",dp[0][0]);
    22     return 0;
    23 }
  • 相关阅读:
    LeetCode: Maximum Product Subarray 解题报告
    LeetCode: Populating Next Right Pointers in Each Node II 解题报告
    LeetCode: Populating Next Right Pointers in Each Node 解题报告
    LeetCode: Word Search 解题报告
    C语言文件操作
    多线程
    C语言函数指针的使用
    进程
    网络编程
    进程间通信——管道通信
  • 原文地址:https://www.cnblogs.com/kickit/p/9004152.html
Copyright © 2011-2022 走看看