poj 2096 Collecting Bugs

来源:互联网 发布:电动车选购 知乎 编辑:程序博客网 时间:2024/06/03 17:53

Problem

poj.org/problem?id=2096

vjudge.net/contest/151678#problem/Q

Reference

blog.csdn.net/xingyeyongheng/article/details/25179481

blog.csdn.net/zy691357966/article/details/46776199(概率dp入门)

www.cnblogs.com/kuangbin/archive/2012/10/02/2710606.html(概率dp总结 by kuangbin)

wenku.baidu.com/view/1c41152de2bd960590c677a8.html(《信息学竞赛中概率问题求解初探》by 梅诗珂)

wenku.baidu.com/view/90adb02acfc789eb172dc8a8.html(《浅析竞赛中一类数学期望问题的求解》 by 汤可因)

wenku.baidu.com/view/56147518a8114431b90dd81e.html(《有关概率和期望问题的研究》 by 鬲融)

Meaning

Ivan 每天找一个 bug。现有 s 个子系统、n 种 bug,在每一个子系统中找到 bug 的概率永远相同(因为有无数个,概率不变),找到任意种 bug 的概率也永远相同。

要求在每个子系统中都至少找到一个 bug、每个种类的 bug 至少找一个,求所需的天数的期望值。

Analysis

dp[i][j]:已在 i 个子系统中找到 bug,已找到 j 种 bug,为达目的仍需要的期望天数。

显然,对所有 i >= s、j >= n 的 dp[i][j],有:dp[i][j] = 0。

在 dp[i][j] 的状态下,再找一个 bug,可能转去 4 种状态:

1. dp[i+1][j+1]:在一个还没发现过 bug 的子系统中(新系统),找到一种还没发现过的 bug(新 bug),概率是:p1 = (s - i) * (n - j) / (n * s);

2. dp[i+1][j]:在一个还没发现过 bug 的子系统中(新系统),找到一种已经发现过的 bug(旧 bug),概率是:p2 = (s - i) * j / (n * s);

3. dp[i][j+1]:在一个已经发现过 bug 的子系统中(旧系统),找到一种还没发现过的 bug(新 bug),概率是:p3 = i * (n - j) / (n * s);

4. dp[i][j]:在一个已经发现过 bug 的子系统中(旧系统),找到一种已经发现过的 bug(旧 bug),概率是:p4 = i * j / (n * s)。

所以,dp[i][j] = p1 * dp[i+1][j+1] + p2 * dp[i+1][j] + p3 * dp[i][j+1] + p4 * dp[i][j] + 1

移项整理,有:dp[i][j] =  (p1 * dp[i+1][j+1] + p2 * dp[i+1][j] + p3 * dp[i][j+1] + 1) / (1 - p4)

Code

#include <stdio.h>#define N 1000#define S 1000double dp[N+2][S+2] = {{0.0}};int main(){    int n, s, i, j;    scanf("%d%d", &n, &s);    for(i=n; ~i; --i)        for(j=s; ~j; --j)            if(i != n || j != s){int p1 = (n - i) * (s - j),p2 = (n - i) * j,p3 = i * (s - j),p4 = i * j;dp[i][j] = (p1 * dp[i+1][j+1] +p2 * dp[i+1][j] +p3 * dp[i][j+1] +n * s) / (n * s - p4);}    printf("%.4f\n", dp[0][0]);    return 0;}

0 0
原创粉丝点击